Was ist der Unterschied zwischen dem Befehl
$ env FOO=bar baz
und
$ FOO=bar baz
Welchen Effekt hat envdas?
Was ist der Unterschied zwischen dem Befehl
$ env FOO=bar baz
und
$ FOO=bar baz
Welchen Effekt hat envdas?
Antworten:
Sie sind funktional gleichwertig.
Der Hauptunterschied besteht darin, dass env FOO=bar bazein zwischengeschalteter Prozess zwischen der Shell und aufgerufen wird baz, der wie bei FOO=bar bazder Shell direkt aufgerufen wird baz.
Also in dieser Hinsicht FOO=bar bazbevorzugt.
Die einzigen Situationen, env FOO=barin denen ich mich befinde, sind Situationen, in denen ich einen Befehl an einen anderen Befehl übergeben muss.
Nehmen wir als konkretes Beispiel an, ich habe ein Wrapper-Skript, das einige Änderungen an der Umgebung vornimmt und dann execden Befehl aufruft, der an das Skript übergeben wurde, wie zum Beispiel:
#!/bin/bash
FOO=bob
some stuff
exec "$@"
Wenn Sie es ausführen myscript FOO=bar baz, execwird ein exec FOO=bar bazungültiger Fehler ausgegeben.
Stattdessen nennst du es als myscript env FOO=bar bazwas ausgeführt wird als exec env FOO=bar bazund ist vollkommen gültig.
FOO=bar exec bazaber, also brauchst du envin deinem letzten Punkt nicht.
execetwas tun, nutzt es Ihre aktuelle Umgebung?
sudo FOO=bar bazUmgebungsvariablen übergeben, ohne dass dies erforderlich ist env.
FOO=bardas Skript einfügen möchte . Wenn dies FOOnicht immer der barFall ist, möchte ich es nicht hart codieren und stattdessen weitergeben.
exec, wie z FOO=bar exec baz.
In diesem speziellen Beispiel gibt es keinen effektiven Unterschied, vorausgesetzt, Ihre Shell ist eine POSIX-kompatible Shell, und vorausgesetzt, es bazhandelt sich um eine ausführbare Datei und nicht um eine eingebaute Shell.
Wenn Ihre Shell beispielsweise keine POSIX-kompatible Shell ist cshodertcsh die Syntax
FOO=bar baz
funktioniert nicht und es gibt keine äquivalente Shell-Syntax. Für diese Shells ist der envBefehl die einzige Möglichkeit, Umgebungsvariablen für einen einzelnen Befehl zu überschreiben oder einzufügen.
Wenn bazeine Shell - builtin ist, sagen sie fczum Beispiel dann envnicht die gleichen Ergebnisse liefern, weil envein neues Verfahren ausgeführt wird, anstatt dass sie direkt von dem Kommando - Shell ausgeführt werden . Darüber hinaus gibt es keine fcausführbare Datei, kann es nur als Shell - builtin ausgeführt werden , da der Weg , um es mit dem Shell - Umgebung interagiert, und so envwird nie Arbeit mit einem builtin wiefc .
Darüber hinaus envbietet die -iOption, die Sie einen Befehl in einer leeren Umgebung mit nur einer bestimmten Gruppe von Umgebungsvariablen starten kann. Dies envkann beispielsweise beim Starten von Prozessen in hygienisierten Umgebungen sehr nützlich sein
env -i HOME=/tmp/homedir "PATH=`getconf PATH`" "TERM=$TERM" FOO=bar baz
tcshhabe, würde ich schreiben (setenv FOO bar; baz), um die entsprechende Funktion zu erhalten.
Zusätzlich zu dem, was bereits gesagt wurde
VAR=value cmd args > redirs
Da es sich um eine Shell-Funktion (Bourne / POSIX) handelt, ist der Name der Umgebungsvariablen, an die Sie übergeben, beschränkt cmd. Sie müssen gültige Shell-Variablennamen sein und dürfen keine schreibgeschützten oder speziellen Variablen für die Shell sein.
Zum Beispiel können Sie nicht tun:
1=foo cmd
Oder
+++=bar cmd
bash erlaubt dir nicht:
SHELLOPTS=xtrace cmd
Während Sie tun können:
env 1=foo cmd
env +++=bar cmd
env '=baz' cmd
(nicht, dass Sie das wollen oder wollen sollten). Oder:
env SHELLOPTS=xtrace cmd
(Ich muss das manchmal tun).
Beachten Sie, dass envSie immer noch keine Umgebungsvariablenzeichenfolge übergeben können, die kein a enthält =(nicht, dass Sie das auch tun möchten).
Eine Verwendung von envist, die $PATHSuche nach ausführbaren Dateien in Shebang-Zeilen zuzulassen (da dies bei der Suche nach der ausführbaren Datei envberücksichtigt wird $PATH). Dies ist nützlich, wenn sich die ausführbare Datei, die Sie aufrufen möchten, möglicherweise an verschiedenen Stellen auf verschiedenen Computern befindet. Beispielsweise,
#!/usr/bin/env perl
in der ersten Zeile eines Skripts mit ausführbaren Bit gesetzt wird dieses Skript mit Perl ausführen , egal , ob es installiert ist /usr/bin/perloder in /usr/local/bin/perloder in einem ganz anderen Ort, solange das Verzeichnis in dem Pfad.
Natürlich bringt diese Pfadsuche ein zusätzliches Risiko mit sich, aber dann ist das Risiko nicht größer, als wenn Sie es explizit geschrieben hätten perl yourscript.pl, wodurch auch Perl im Suchpfad nachgeschlagen wird.
Ein anderes Mal, wenn enves wirklich nützlich ist, möchten Sie die Umgebung vollständig steuern. Ich führe ein Serverprogramm aus (Informix, falls Sie es nicht erraten können), dessen Umgebung ich vollständig steuern möchte. Ich führe es envam Ende eines Skripts aus, das eine Reihe von Variablen auf die richtigen Werte setzt:
env -i HOME="$IXD" \
INFORMIXDIR="$IXD" \
INFORMIXSERVER="$IXS" \
${IXC:+INFORMIXCONCSMCFG="$IXC"} \
${IXH:+INFORMIXSQLHOSTS="$IXH"} \
IFX_LISTEN_TIMEOUT=3 \
ONCONFIG="onconfig.$IXS" \
PATH="/bin:/usr/bin:$IXD/bin" \
SHELL=/bin/ksh \
TZ=UTC0 \
$ONINIT "$@"
Die -iOption zappt die vorhandene Umgebung. Die nachfolgenden VAR=valueOptionen legen die Umgebungsvariablen fest, die ich festlegen möchte. Der Name des Programms ist in $ONINITund alle Befehlszeilenargumente werden wörtlich mit übergeben "$@".
Das ${IXH:+INFORMIXSQLHOSTS="$IXH"}Konstrukt wird nur übergeben INFORMIXSQLHOSTS="$IXH", envwenn $IXHein nicht leerer Wert festgelegt ist.