Arguments

在這種情況下,為什麼我可以將參數傳遞給 /usr/bin/env?

  • November 30, 2021

我在另一個答案中讀到,我無法將參數傳遞給解釋器,而不是提供給/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

二、帶-fflag:

$ 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可能在/binor/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+"$@"}改用。)

引用自:https://unix.stackexchange.com/questions/361794