Linux上的ZSH不';无法识别shell脚本中的有效选项
Linux上的ZSH不';无法识别shell脚本中的有效选项,linux,shell,command-line,zsh,shebang,Linux,Shell,Command Line,Zsh,Shebang,zsh不识别用-o设置的选项,但仅当它在shebang中,并且在Linux上时才识别 以下脚本在zsh 5.0.2、zsh 5.6和最新git上失败: #!/bin/zsh -o pipefail thiswillfail | echo 'hello, world' echo $? exit 预期产出 hello, world /home/prajjwal/script:2: command not found: thiswillfail 127 /bin/zsh: no such opti
zsh
不识别用-o
设置的选项,但仅当它在shebang中,并且在Linux
上时才识别
以下脚本在zsh 5.0.2
、zsh 5.6
和最新git上失败:
#!/bin/zsh -o pipefail
thiswillfail | echo 'hello, world'
echo $?
exit
预期产出
hello, world
/home/prajjwal/script:2: command not found: thiswillfail
127
/bin/zsh: no such option: pipefail
实际产出
hello, world
/home/prajjwal/script:2: command not found: thiswillfail
127
/bin/zsh: no such option: pipefail
什么有效
- MacOS Mojave上的
脚本。不过,到目前为止,我尝试过的每个zsh 5.3
版本似乎都失败了Linux
- 在终端上手动调用
/bin/zsh-o pipefail
- 在脚本中的shebang之后使用
设置选项set-o pipefail
- 清空我的
,以确保我的某个设置不会导致此问题.zshrc
虽然我只是想让
pipefail
工作,但这拒绝了我尝试设置的任何其他选项,即使它们都在zshoptions
中提到,这是尝试在上设置选项的一个陷阱代码>行。内核只在第一个空间分割shebang行
当你说
#!/bin/zsh -o pipefail
最后执行的命令是“/bin/zsh”“-o pipefail”“/home/prajjwal/script”
错误消息指出“pipefail”
(注意前导空格)不是有效选项,这是正确的:只有“pipefail”
有效
在这种情况下,一种可能的解决方法是将所有内容塞进一个命令行参数中:
#!/bin/zsh -opipefail
但总的来说这是不可能的,#代码>接口不允许您传递多个额外参数,因此您可以选择查找其他解决方法(例如,使用手动设置
)或编写包装器脚本:
#!/bin/zsh
exec /bin/zsh -o pipefail /path/to/the/real/script
在某些系统上,另一种选择是可用的:env-S
。此选项不是POSIX指定的,也不是在所有系统上都可用。它适用于(包括所有标准Linux发行版)和,但不适用于或。我找不到任何关于MacOS的信息
(注意:GNU env还支持将--split string
作为可选(长)选项名,但FreeBSD env不支持。)
用法:
#!/usr/bin/env -S /bin/zsh -o pipefail
这将使用单个长参数('-S/bin/zsh-o pipefail'
)调用env
。标准选项处理将其视为-S
选项,后跟一个参数('/bin/zsh-o pipefail'
)
在这样一个简单的例子中,env-S
在空格/制表符上拆分参数,并将结果列表视为原始命令行的一部分:
env -S ' /bin/zsh -o pipefail'
# works the same as:
env /bin/zsh -o pipefail
在不太简单的情况下,您必须引用一些字符(env-S
专门处理空格、“
、”
、\
、$
,等等)。特别是,它的工作方式不同于shell引用。有关详细信息,请参阅上面链接的手册页。这是试图在!
行上设置选项的一个陷阱。内核仅在第一个空格处拆分shebang行
当你说
#!/bin/zsh -o pipefail
最后执行的命令是“/bin/zsh”“-o pipefail”“/home/prajjwal/script”
错误消息指出“pipefail”
(注意前导空格)不是有效选项,这是正确的:只有“pipefail”
有效
在这种情况下,一种可能的解决方法是将所有内容塞进一个命令行参数中:
#!/bin/zsh -opipefail
但通常情况下,这是不可能的,#!
接口不允许您传递多个额外参数,因此您可以选择查找其他解决方法(例如,使用手动设置
)或编写包装器脚本:
#!/bin/zsh
exec /bin/zsh -o pipefail /path/to/the/real/script
在某些系统上,另一种选择是可用的:env-S
。此选项不是POSIX指定的,也不是在所有系统上都可用。它可以在(包括所有标准Linux发行版)和上工作,但不能在或上工作。我找不到有关MacOS的任何信息
(注意:GNU env还支持将--split string
作为可选(长)选项名,但FreeBSD env不支持。)
用法:
#!/usr/bin/env -S /bin/zsh -o pipefail
这将使用单个长参数('-S/bin/zsh-o pipefail'
)调用env
。标准选项处理将其视为-S
选项,后跟一个参数('/bin/zsh-o pipefail'
)
在这样一个简单的例子中,env-S
在空格/制表符上拆分参数,并将结果列表视为原始命令行的一部分:
env -S ' /bin/zsh -o pipefail'
# works the same as:
env /bin/zsh -o pipefail
在不太简单的情况下,您必须引用一些字符(env-S
处理空格,“
,”
,\
,$
等)。特别是,它不像shell引用那样工作。有关详细信息,请参阅上面链接的手册页。使用/usr/bin/env
有一个拆分字符串选项,这是一种半便携的方式。我的shebang就变成了#/usr/bin/env-S/bin/zsh-o pipefail
。这是我现在首选的解决方案,考虑将它添加到您的答案中。使用<代码> /Ur/bin /Env有一个拆分字符串选项,它是一种半便携的方式。我的shebang就变成了#/usr/bin/env-S/bin/zsh-o pipefail
。这是我现在喜欢的解决方案,考虑把它添加到你的答案中。