这个以双连字符 (--) 开头的 shebang 是如何工作的?

Ang*_*ocA 17 scripting shell-script sql shebang db2

我在 RosettaCode 页面中发现了以下类型的 shebang:

--() { :; }; exec db2 -txf "$0"
Run Code Online (Sandbox Code Playgroud)

它适用于 Db2,也适用于 Postgres。但是,我不明白整行。

我知道双破折号是 SQL 中的注释,之后它调用 Db2 可执行文件,并使用一些参数将文件本身作为文件传递。但是括号,卷曲的刹车,冒号和分号怎么样,以及如何替换真正的shebang #!?

https://rosettacode.org/wiki/Multiline_shebang#PostgreSQL

Kus*_*nda 21

相关:哪个 shell 解释器运行一个没有 shebang 的脚本?

该脚本没有 shebang/hashbang/#!行,仅仅是因为双破折号不是#!.

但是,脚本将由 shell 执行(请参阅上面链接的问题和答案),并且在该 shell 中,如果-是函数名称中的有效字符,则该行声明一个调用的 shell 函数,该函数--不执行任何操作(好吧,它运行:什么都不做),并且从不调用。

该函数,采用更常见的多行符号(只是为了让它看起来更明显,因为它的奇怪名称有点掩盖了它实际上是一个函数的事实):

-- () {
  :
}
Run Code Online (Sandbox Code Playgroud)

函数定义的唯一目的是让一行在 shell 脚本中有效,同时还有一个有效的 SQL 命令(注释)。这种代码称为多语言

在声明了伪造的 shell 函数之后,脚本在由 shell 脚本解释器执行时,用于exec将当前的 shell 替换为运行产生的进程db2 -txf "$0",这db2 -txf与在命令行中使用脚本的路径名相同。

此技巧可能无法在基于dash或其他ash基于 shell、yash、Bourne shellksh88ksh93用作 的系统上可靠地工作/bin/sh,因为这些 shell 不接受名称包含破折号的函数。

还相关:


我想以下也可以工作(没有真正测试过):

--() { exec db2 -txf "$0"; }; --
Run Code Online (Sandbox Code Playgroud)


Unc*_*lly 7

正如@Kusalananda 已经说过的那样,该技巧已失效,并且不适用于所有 shell。

这是我对便携性的看法:

--/.. 2>/dev/null; exec db2 -txf "$0"
Run Code Online (Sandbox Code Playgroud)

即使--当前目录中存在名为的文件/目录,第一个命令也应该失败,并且任何错误都将被关闭2>/dev/null;然后 shell 将继续执行第二个命令,即exec.