
我讀到另一個答案我無法將參數傳遞給解釋器,而不是傳遞給/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+"$@"}
。