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

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

我在RosettaCode页面找到了以下类型的shebang:

--() { :; }; exec db2 -txf "$0"

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

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

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

答案1

有关的:哪个 shell 解释器运行不带 shebang 的脚本?

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

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

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

-- () {
  :
}

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

声明伪造的 shell 函数后,该脚本在由 shell 脚本解释器执行时,会使用execrunning 产生的进程替换当前 shell ,这与从命令行在脚本的路径名上db2 -txf "$0"使用相同。db2 -txf

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

相关内容:


我想以下也可以工作(未经真正测试):

--() { exec db2 -txf "$0"; }; --

答案2

正如@Kusalananda 已经说过的那样,这个技巧已经被破坏了,并且它不能在所有 shell 中工作。

以下是我对可移植性的看法:

--/.. 2>/dev/null; exec db2 -txf "$0"

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

相关内容