在這種情況下,為什麼我可以將參數傳遞給 /usr/bin/env?
我在另一個答案中讀到,我無法將參數傳遞給解釋器,而不是提供給
/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
flag:$ 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
一些 Unices,尤其是 macOS(以及直到 2005 年的 FreeBSD)將允許這樣做,而 Linux 則不會,但是…
如果使用
env
最新版本的 GNU coreutils 包(8.30+)中的實用程序,它有一個非標準-S
選項,允許在行中提供多個參數#!
。相反的問題:帶有
#!/usr/bin/env command --argument
的 Shebang 行在 Linux 上失敗
您不能將多個參數*可移植地傳遞給解釋器。*特別是,Linux 不支持它。
一些 Unix 變體確實支持 shebang 行上的多個參數。現代 macOS 系統和其他一些系統就是這種情況。有關Unix 變體比較表和大量歷史資訊,請參閱Sven Mascheck 的 shell 可移植性頁面。
如果你想擁有一個可移植的 awk 腳本,那麼就沒有一個好的解決方案。
#!/usr/bin/env
並且#!/bin/sh
是唯一在實踐中可移植的 shebang 行:根據 Unix 變體,awk
可能在/bin
or/usr/bin
或其他一些位置(例如/usr/xpg4/bin/awk
,在 Solaris 上獲得 POSIX 之一 - in/usr/bin
用於遺留應用程序)。由於#!/usr/bin/env awk -f
不能便攜工作,因此#!/bin/sh
. (/bin/sh
可能是傳統的 Bourne shell 而不是現代的 POSIX shell,但任何 Unix 平台在實踐中都有一些東西。)這個想法是編寫一個polyglot,即一個腳本,sh
解釋為執行 awk 的指令,而 awk 解釋為所需的腳本. 這甚至適用於無法辨識 shebang 行但預設為sh
用於腳本執行(一些古老的 unice,或非 Unix 核心上的一些類 unix 使用者空間)。#!/bin/sh "exec" "awk" "-f" "$0" "$@" && 0 {} … # awk script here
(如果對古代 unice 的可移植性是一個問題,請參閱Sven Mascheck 的支持頁面並
"$@"
考慮${1+"$@"}
改用。)