Ich habe Folgendes versucht, aber es scheint nicht zu funktionieren:
$ cat script.sh
#!/bin/env -i /bin/sh
/bin/env
$ script.sh
/bin/env: invalid option -- ' '
Try `/bin/env --help' for more information.
bash
shell-script
env
balki
quelle
quelle
Antworten:
Der Grund, warum dies nicht funktioniert, liegt darin, dass es
-i /bin/sh
als einziges Argument fürenv
. Normalerweise wären dies 2 Argumente-i
und/bin/sh
. Dies ist nur eine Einschränkung des Schebangs. Daran führt kein Weg vorbei.Sie können diese Aufgabe jedoch auf eine andere Weise ausführen.
Wenn Sie möchten, dass diese Aufgabe vom Skript selbst ausgeführt wird und Sie nicht so etwas tun müssen
env -i script.sh
, können Sie das Skript selbst erneut ausführen lassen.Dadurch wird das Skript von selbst erneut ausgeführt, wenn die
CLEANED
Umgebungsvariable nicht festgelegt ist. Bei erneuter Ausführung setzt es die Variable, um sicherzustellen, dass sie nicht in eine Schleife gerät.quelle
env
von den GNU-Coreutils haben nun die Option-S
, Probleme zu umgehen, die diesem ähnlich sind, aber nicht genau gleich sind. Zum Beispiel#!/usr/bin/env -S perl -T
.#!/usr/bin/env -S -i /bin/sh
. Achten Sie auf Portabilitätsprobleme.Führen Sie Ihr Skript aus mit
env -i
:Und das Drehbuch wie gewohnt:
Wenn Sie mit einer sauberen Umgebung ausführen möchten, ohne dies beim Ausführen ausdrücklich zu erwähnen. Eduardo Ivanec gibt in dieser Antwort einige Ideen , mit denen Sie Ihr Skript rekursiv aufrufen können,
exec
wenn die Umgebung nicht sauber ist (z. B. $ HOME ist definiert):quelle
Mit bash kannst du das so machen:
Die Befehle
set -e
undset -u
sind nicht unbedingt erforderlich, aber ich füge sie hinzu, um zu demonstrieren, dass dieser Ansatz nicht auf den Zugriff auf nicht gesetzte Variablen (wie z. B.[ "$HOME" != "" ]
) angewiesen ist und mit einerset -e
Einstellung kompatibel ist .Das Testen der
HOME
Variablen sollte sicher sein, da bash Skripte im nicht interaktiven Modus ausführt, dh Konfigurationsdateien wie~/.bashrc
(wo Umgebungsvariablen gesetzt werden können) werden beim Start nicht bezogen.Beispielausgabe:
quelle
Leider funktioniert das nicht so - Linux ist
-i /bin/sh
ein Argument, an das weitergegeben werden mussenv
(siehe Shebang ).quelle
Die Linux-2-Argument-Shebang-Beschränkung (Interpeter + einzelnes Argument) ist in den meisten Antworten vermerkt, aber zu sagen, dass dies nicht möglich ist, ist falsch - Sie müssen nur zu einem Interpreter wechseln, der mit einem einzelnen Argument etwas Nützliches bewirken kann:
Dies geschieht
perl
mit einem einzeiligen Skript (-e
), das die Argumente löscht%ENV
(billiger alsenv -i
) und aufruftexec /bin/sh
, wobei die Argumente korrekt angegeben werden.perl
Bei Bedarf kann weitere Logik hinzugefügt werden (obwohl dies unter Linux nicht viel ist, da Sie sich aufBINPRM_BUF_SIZE
Zeichen beschränken , was wahrscheinlich 128 ist).Leider ist dies Linux-spezifisch und funktioniert nicht auf einem System, das mehrere shebang-Argumente zulässt: - /
perl
Diese Zeichenfolge wird als einzelnes Argument verarbeitet. Sie wird daher nicht in Anführungszeichen gesetzt, wie dies normalerweise inperl -e ...
der Befehlszeile der Fall ist. Wenn Sie Anführungszeichen hinzufügen, werden diese beibehalten. Perl erkennt nur eine Literalzeichenfolge, die Warnungen enthält, und beschwert sich über eine unbrauchbare Zeichenfolge Konstante).Beachten Sie auch, dass sich das Verhalten geringfügig ändert, wenn es auf diese Weise verwendet wird,
@ARGV
normalerweise nur die Argumente$0
enthält und das Skript enthält. In diesem Fall$ARGV[0]
ist shebang der Name des Skripts (und$0
ist-e
), was es ein wenig einfacher macht.Sie können dies auch mit einem Interpreter lösen, der seine Befehlszeile (ohne ein zusätzliches
-c
Argument) "erneut verarbeitet", wie es das alte AT & Tksh93
tut:obwohl das
ksh
heutzutage vielleicht nicht mehr so ist ;-)(
bash
hat eine ähnliche Funktion mit--wordexp
, ist aber in den Versionen, in denen es funktioniert, "undokumentiert" und in den Versionen, in denen es dokumentiert ist, zur Kompilierungszeit nicht aktiviert: - / Es kann auch nicht dafür verwendet werden, da es zwei Argumente benötigt. ..)Auch effektiv eine Variation der Antworten von @Patrick und @ maxschlepzig:
Anstatt Verwendung eine neue Variable Er nutzt die spezielle „
_
“ Variable, wenn es nicht gesetzt ist , genau zu „bash“ dann das Skript ersetzenexec
verwenden-a
zu machenARGV[0]
(und damit$_
) nur „bash“, und mit-c
der Umwelt zu löschen.Alternativ, wenn es akzeptabel ist, die Umgebung zu Beginn des Skripts zu bereinigen (nur Bash):
Das verwendet
compgen
(Completion Helper), um die Namen aller exportierten Umgebungsvariablen aufzulisten, undunset
s sie auf einmal.Siehe auch Mehrere Argumente in shebang für weitere Details zum allgemeinen Problem des shebang-Verhaltens.
quelle