我想知道是否有通过 shebang 行 ( #!
)将多个选项传递给可执行文件的通用方法。
我使用 NixOS,在我编写的任何脚本中,shebang 的第一部分通常是/usr/bin/env
. 然后我遇到的问题是系统将其后的所有内容解释为单个文件或目录。
例如,假设我想编写一个脚本以bash
在 posix 模式下执行。写shebang的天真方式是:
#!/usr/bin/env bash --posix
Run Code Online (Sandbox Code Playgroud)
但是尝试执行生成的脚本会产生以下错误:
/usr/bin/env: ‘bash --posix’: No such file or directory
Run Code Online (Sandbox Code Playgroud)
我知道这篇文章,但我想知道是否有更通用和更清洁的解决方案。
编辑:我知道对于Guile脚本,有一种方法可以实现我想要的,在手册的第 4.3.4 节中记录:
#!/usr/bin/env sh
exec guile -l fact -e '(@ (fac) main)' -s "$0" "$@"
!#
Run Code Online (Sandbox Code Playgroud)
这里的技巧是,第二行(以 开头exec
)被解释为代码,sh
但是,在#!
...!#
块中,作为注释,因此被 Guile 解释器忽略。
难道不能将此方法推广到任何解释器吗?
第二次编辑:在玩了一会儿之后,似乎对于可以从中读取输入的解释器,stdin
以下方法可以工作:
#!/usr/bin/env sh
sed '1,2d' "$0" | bash --verbose --posix …
Run Code Online (Sandbox Code Playgroud) 我有一个简单的脚本:
#!/usr/bin/env ruby --verbose
# script.rb
puts "hi"
Run Code Online (Sandbox Code Playgroud)
在我的 OSX 机器上,它运行良好:
osx% ./script.rb
hi
Run Code Online (Sandbox Code Playgroud)
但是,在我的 linux 机器上,它会引发错误
linux% ./script.rb
/usr/bin/env: ruby --verbose: No such file or directory
Run Code Online (Sandbox Code Playgroud)
如果我手动运行 shebang 线,它工作正常
linux% /usr/bin/env ruby --verbose ./script.rb
hi
Run Code Online (Sandbox Code Playgroud)
但是如果我打包ruby --verbose
成一个参数,我可以复制错误env
linux% /usr/bin/env "ruby --verbose" ./script.rb
/usr/bin/env: ruby --verbose: No such file or directory
Run Code Online (Sandbox Code Playgroud)
所以我认为这是如何env
解释shebang线的重置的问题。我正在使用 GNU coreutils 8.4 env
:
linux% /usr/bin/env --version
env (GNU coreutils) 8.4
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL …
Run Code Online (Sandbox Code Playgroud)