
Ich lese ineine andere Antwortdass ich dem Interpreter keine anderen Argumente übergeben kann als /usr/bin/env
:
Ein weiteres potenzielles Problem besteht darin, dass
#!/usr/bin/env
Sie mit dem Trick keine Argumente an den Interpreter übergeben können (mit Ausnahme des Namens des Skripts, der implizit übergeben wird).
Es sieht jedoch so aus, als ob ich dazu in der Lage wäre, da awk
es kaputt geht, wenn ich ihm die Flagge nicht gebe -f
, und behoben ist, wenn ich ihm die Flagge gebe -f
, während ich Folgendes verwende /usr/bin/env
:
Erstens ohne Flagge -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
Zweitens mit der -f
Flagge:
$ 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"
- Wenn also nach derverknüpfte AntwortIch kann keine Flags an den Interpreter übergeben. Warum kann ich das
-f
Flag an übergebenawk
?
Ich renne macOS
:
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.12.1
BuildVersion: 16B2657
Antwort1
Einige Unix-Versionen, insbesondere macOS (und bis 2005 FreeBSD), erlauben dies, Linux nicht, aber ...
Wenn Sie das env
Dienstprogramm aus einer aktuellen Version des GNU-Coreutils-Pakets (8.30+) verwenden, verfügt es über eine nicht standardmäßige Option, die die Angabe mehrerer Argumente in Zeilen -S
ermöglicht .#!
Die gegenteilige Frage:Shebang-Zeile mit `#!/usr/bin/env command --argument` schlägt unter Linux fehl
Antwort2
Sie können nichttragbarÜbergeben Sie mehrere Argumente an den Interpreter. Insbesondere Linux unterstützt dies nicht.
Einige Unix-Varianten unterstützen mehr als ein Argument in der Shebang-Zeile. Dies ist auf modernen macOS-Systemen und einigen anderen der Fall. SieheSven Maschecks Shell-PortabilitätsseiteFür einVergleichstabelle für Unix-Variantenund viele historische Informationen.
Wenn Sie ein portables Awk-Skript haben möchten, gibt es keine gute Lösung. #!/usr/bin/env
und #!/bin/sh
sind die einzigen Shebang-Zeilen, die in der Praxis portierbar sind: Abhängig von der Unix-Variante awk
können sie in /bin
oder /usr/bin
oder an anderen Stellen stehen (z. B. /usr/xpg4/bin/awk
unter Solaris, um eine POSIX-Shell zu erhalten – die in /usr/bin
ist für ältere Anwendungen). Da #!/usr/bin/env awk -f
nicht portabel funktioniert, bleibt übrig #!/bin/sh
. ( /bin/sh
kann eine ältere Bourne-Shell statt einer modernen POSIX-Shell sein, aber jede Unix-Plattform hat dort in der Praxis etwas.) Die Idee ist, eine zu schreibenmehrsprachig, also ein Skript, das sh
als Anweisung zum Ausführen von awk interpretiert wird und das awk als das gewünschte Skript interpretiert. Dies funktioniert sogar auf Systemen, die Shebang-Zeilen nicht erkennen, aber standardmäßig sh
für die Skriptausführung verwenden (einige antike Unix-Systeme oder einige unixähnliche Benutzerländer auf Nicht-Unix-Kerneln).
#!/bin/sh
"exec" "awk" "-f" "$0" "$@" && 0 {}
… # awk script here
(Wenn die Portabilität zu alten Unix-Systemen ein Problem darstellt, sieheSven Maschecks Seiteauf "$@"
Support und erwägen Sie ${1+"$@"}
stattdessen die Verwendung.)