我在RosettaCode页面找到了以下类型的shebang:
--() { :; }; exec db2 -txf "$0"
它适用于 Db2,也适用于 Postgres。但是,我不明白整条线。
我知道双破折号是 SQL 中的注释,之后它调用 Db2 可执行文件,并使用一些参数将文件本身作为文件传递。但是括号、花括号、冒号和分号又如何呢?如何替换真正的 shebang #! ?
答案1
有关的:哪个 shell 解释器运行不带 shebang 的脚本?
该脚本没有 shebang/hashbang/#!
行,只是因为双破折号不是#!
。
但是,该脚本将由 shell 执行(请参阅上面链接的问题和答案),并且在该 shell 中,如果-
是函数名称中的有效字符,则该行声明一个名为的 shell 函数,--
该函数不执行任何操作(好吧,它运行:
,什么都不做)并且从未被调用过。
该函数采用更常见的多行表示法(只是为了使其看起来更明显,因为它奇怪的名称有点掩盖了它实际上是一个函数的事实):
-- () {
:
}
函数定义的唯一目的是在 shell 脚本中具有有效的行,同时具有有效的 SQL 命令(注释)。这种代码称为多语言。
声明伪造的 shell 函数后,该脚本在由 shell 脚本解释器执行时,会使用exec
running 产生的进程替换当前 shell ,这与从命令行在脚本的路径名上db2 -txf "$0"
使用相同。db2 -txf
此技巧可能无法在使用dash
或其他ash
基于 shell yash
、Bourne shellksh88
或ksh93
用作 的系统上可靠地工作/bin/sh
,因为这些 shell 不接受名称包含破折号的函数。
相关内容:
我想以下也可以工作(未经真正测试):
--() { exec db2 -txf "$0"; }; --
答案2
正如@Kusalananda 已经说过的那样,这个技巧已经被破坏了,并且它不能在所有 shell 中工作。
以下是我对可移植性的看法:
--/.. 2>/dev/null; exec db2 -txf "$0"
即使当前目录中存在名为 的文件/目录,第一个命令也应该失败,--
并且任何错误都将被2>/dev/null
;关闭。然后 shell 将继续执行第二个命令,即exec
.