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 #!?
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 shellksh88
或ksh93
用作 的系统上可靠地工作/bin/sh
,因为这些 shell 不接受名称包含破折号的函数。
还相关:
我想以下也可以工作(没有真正测试过):
--() { exec db2 -txf "$0"; }; --
Run Code Online (Sandbox Code Playgroud)
正如@Kusalananda 已经说过的那样,该技巧已失效,并且不适用于所有 shell。
这是我对便携性的看法:
--/.. 2>/dev/null; exec db2 -txf "$0"
Run Code Online (Sandbox Code Playgroud)
即使--
当前目录中存在名为的文件/目录,第一个命令也应该失败,并且任何错误都将被关闭2>/dev/null
;然后 shell 将继续执行第二个命令,即exec
.