kjo*_*kjo 3 scripting zsh env shebang
我收到错误
/usr/bin/env: zsh -: No such file or directory
Run Code Online (Sandbox Code Playgroud)
...当我运行以zsh以下shebang行开头的可执行脚本时:
#!/usr/bin/env zsh -
Run Code Online (Sandbox Code Playgroud)
此外,FWIW,替换-为--原因/usr/bin/env打印关于zsh --.
我只在 ubuntu 下看到过这个错误,而且只在 shebang hack 的上下文中看到过。在达尔文下,相同的脚本运行良好。在 ubuntu 下,运行
% /usr/bin/env zsh -
Run Code Online (Sandbox Code Playgroud)
从命令行成功。(实际上,“在 ubuntu 下”应该理解为“在 ubuntu 12.04 LTS 和env (GNU coreutils) 8.13”下的简写。)
我的问题是:如何修改上面的shebang以避免此错误?
当然,我知道删除尾随-会消除错误,但这不是一个可以接受的解决方案。这篇文章的其余部分解释了原因。
导致错误的 shebang 行是为了遵守两个完全独立的准则:
要使脚本可移植,请使用#!/usr/bin/env <cmd ...>而不是#!/path/to/cmd <...>.
把-作为唯一参数zsh在zsh的脚本横座板某类的家当线的攻击。
所以,我可以更准确地重申我的问题如下:是否有可能同时满足这两个准则而不会在 ubuntu 下触发上面显示的错误?
Linux(您提到“仅在 Ubuntu 下”,但您提到的唯一操作系统是 Darwin)不支持将多个参数传递给“shebang”解释器。它将整个字符串(在您的情况下,"zsh -")作为单个参数传递。
确保您的包不依赖于解释器位置的正确方法是,作为安装过程的一部分,定位解释器并修改脚本以包含正确的路径。http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sh.html#tag_20_117_16sh提供了一些用于执行此操作的示例代码(用于)。
我认为你的问题的答案基本上是“不”。Shebang 机制并不那么灵活。
该#!行仅允许您指定要执行的命令以及(可选)该命令的单个参数。脚本的名称作为另一个参数传递。所以如果foo.zsh开始于:
#!/usr/bin/env zsh
Run Code Online (Sandbox Code Playgroud)
跑步foo.zsh就相当于跑步/usr/bin/env zsh foo.zsh。
如果直接指定路径zsh,则可以传递附加参数:
#!/usr/bin/zsh -
Run Code Online (Sandbox Code Playgroud)
但有了#!/usr/bin/envhack,zsh 就有了额外的争论。
显然,正如您所见,这种行为因系统而异。顺便说一句,我会检查以确保-Ubuntu 上的 没有被忽略。
如果您可以依赖zsh在您关心的所有系统上处于一致的位置,则可以使用#!/usr/bin/zsh -(忽略您的第一个准则)。
如果不能,那么您可以zsh在每个系统上的一致位置创建符号链接,也可以#!在安装脚本时修改脚本中的行。(在 Perl 并不总是存在的日子里,我自己为 Perl 脚本做过这个/usr/bin/perl。)
或者,您可以编写一个包装器,当不带参数调用时,使用zsh参数调用-,并将 shebang 更改为:
#!/usr/bin/env zsh-wrapper
Run Code Online (Sandbox Code Playgroud)
它只需要zsh-wrapper位于 中的某个位置$PATH,不一定位于一致的位置。
另请参阅这个问题和我的回答,以讨论#!/usr/bin/env黑客的优点和缺点。
请参阅此页面,了解有关各种类 Unix 系统上 shebang 行为的更多信息(感谢 Stephane Chazelas 提供的链接)。
| 归档时间: |
|
| 查看次数: |
15806 次 |
| 最近记录: |