我读到另一个答案我无法将参数传递给解释器,而不是我所提供的/usr/bin/env
:
另一个潜在的问题是,该
#!/usr/bin/env
技巧不允许您将参数传递给解释器(除了隐式传递的脚本名称之外)。
然而,看起来我能够做到,因为awk
当我不给它标志时它会被破坏-f
,而当我给它标志时它会被修复-f
,同时使用/usr/bin/env
:
首先,没有-f
标志:
$ cat wrap_in_quotes
#!/usr/bin/env awk
# wrap each line in quotes
# usage: wrap_in_quotes [ file ... ]
{ print "\""$0"\"" }
$ echo foobar | ./wrap_in_quotes
awk: syntax error at source line 1
context is
>>> . <<< /wrap_in_quotes
awk: bailing out at source line 1
二、带-f
旗:
$ vim wrap_in_quotes
$ cat wrap_in_quotes
#!/usr/bin/env awk -f
# wrap each line in quotes
# usage: wrap_in_quotes [ file ... ]
{ print "\""$0"\"" }
$ echo foobar | ./wrap_in_quotes
"foobar"
- 那么,如果根据链接答案我无法将标志传递给解释器,为什么我能够将标志传递
-f
给awk
?
我在跑macOS
:
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.12.1
BuildVersion: 16B2657
答案1
一些 Unices,尤其是 macOS(以及 2005 年之前的 FreeBSD)将允许这样做,而 Linux 则不允许,但是……
如果使用env
最新版本的 GNU coreutils 包 (8.30+) 中的实用程序,它有一个非标准-S
选项,允许#!
在行中提供多个参数。
相反的问题:使用 `#!/usr/bin/env command --argument` 的 Shebang 行在 Linux 上失败
答案2
你不能便携式的将多个参数传递给解释器。特别是,Linux 不支持它。
某些 Unix 变体确实支持 shebang 行上的多个参数。现代 macOS 系统和其他一些系统就是这种情况。看Sven Mascheck 的 shell 可移植性页面为一个Unix 变体比较表以及大量的历史信息。
如果您想要一个可移植的 awk 脚本,则没有巧妙的解决方案。#!/usr/bin/env
和#!/bin/sh
是唯一在实践中可移植的 shebang 行:根据 Unix 变体,awk
可能位于/bin
或/usr/bin
,或位于其他一些位置(例如,/usr/xpg4/bin/awk
在 Solaris 上获得 POSIX 行 - 中的行/usr/bin
用于遗留应用程序)。由于#!/usr/bin/env awk -f
不能移植,所以就只剩下#!/bin/sh
. (/bin/sh
可能是传统的 Bourne shell,而不是现代的 POSIX shell,但任何 Unix 平台在实践中都有一些东西。)这个想法是编写一个多语言sh
,即解释为运行 awk 的指令并且 awk 解释为所需脚本的脚本。这甚至适用于无法识别 shebang 行但默认sh
执行脚本的系统(一些古董 unice,或非 Unix 内核上的一些类 unix 用户区)。
#!/bin/sh
"exec" "awk" "-f" "$0" "$@" && 0 {}
… # awk script here
(如果担心古代统一的可移植性,请参阅斯文·马斯切克的页面支持"$@"
并考虑使用${1+"$@"}
。)