Wie führe ich ein Programm in einer sauberen Umgebung in bash aus?

Antworten:

127

Sie können dies tun mit env:

env -i your_command

Im Gegensatz zu den Kommentaren unten, dies tut vollständig aus der Umwelt klar, aber es verhindert nicht , your_commandneue Variablen zu setzen. Insbesondere das Ausführen einer Shell führt dazu, dass die /etc/profileausgeführt wird, und die Shell verfügt möglicherweise auch über einige integrierte Einstellungen.

Sie können dies überprüfen mit:

env -i env

dh wischen Sie die Umgebung und drucken Sie es dann. Die Ausgabe ist leer.

ams
quelle
4
Es räumt die Umwelt nicht vollständig aus: echo 'echo $PATH' > test.sh && chmod u+x test.sh && env -i test.shdruckt /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin.
10.
2
Es scheint jedoch, dies in der Nähe ist man bekommen kann - Es scheint , wie Variablen wie PATH, PWDund SHLVLwird automatisch von Bash gesetzt. +1.
10.
3
@ I0b0: Siehe meine Bearbeitung.
ams
3
Die PATH-Variable im Skript des ersten Kommentators befindet sich nicht in der Umgebung und ist daher keine Umgebungsvariable. Bash setzt anscheinend seine eigene reguläre Shell-Variable namens PATH, wenn keine exportiert wurde: env -i bash --norc -c "declare -p PATH"gives declare -- PATH="/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:.". Beachten Sie das "-x" für exportiert (und daher Teil der Umgebung), wenn Sie es selbst exportieren: env -i bash --norc -c "export PATH; declare -p PATH"gibtdeclare -x PATH="/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:."
Binary Phile
34

Eine "saubere" bashUmgebung kann mit gehabt werden

$ env -i bash --noprofile --norc
  • Der env -iBefehl führt den ihm über die Befehlszeile erteilten Befehl aus, ohne eine der exportierten Umgebungsvariablen der alten Shell-Umgebung in die Umgebung des ausgeführten Programms zu übertragen.

  • Die --noprofileOption stoppt das bashLesen der systemweiten oder persönlichen Shell-Initialisierungsskripten, die ansonsten für eine Anmeldeshell gelesen würden.

  • Die --norcOption stoppt das bashLesen der persönlichen Shell-Initialisierungsskripten, die ansonsten für eine interaktive Shell gelesen würden.

Kusalananda
quelle
Mein Env erkennt diese Optionen nicht.
Paulo Carvalho
@PauloCarvalho Ihr System unterstützt nicht env -i? Auf welchem ​​System bist du?
Kusalananda
Entschuldigung, es funktioniert in der Shell. Ich habe versucht, es in ein Skript zu schreiben und irgendwie warf es einen Fehler.
Paulo Carvalho
@PauloCarvalho Entschuldigung, ich kann nicht sehen, welchen Befehl Sie eingegeben haben oder welchen Fehler Sie haben.
Kusalananda
Großartig - genau das, wonach ich gesucht habe. envmeine Umgebung zu säubern und --noprofilezu vermeiden, / etc / profile und Freunde --norczu beschaffen und zu vermeiden, ~ / .bashrc und Freunde zu beschaffen.
Felipe Alvarez
28

env -i somecommandführt einen Befehl in einer leeren Umgebung aus, wie ams bereits erwähnt hat .

Viele Programme sind auf einige wichtige Umgebungsvariablen angewiesen, daher möchten Sie diese möglicherweise beibehalten:

env -i HOME="$HOME" LC_CTYPE="${LC_ALL:-${LC_CTYPE:-$LANG}}" PATH="$PATH" USER="$USER" somecommand

Alternativ können Sie sich in einer kleinen Umgebung mit Anmeldezeit anmelden.

ssh localhost somecommand
Gilles
quelle
1
Funktioniert, wenn der Befehl in cmdline ausgeführt wird. Wie stelle ich das in shebang ?, scheint nicht zu funktionieren !
Balki
Seltsamerweise unterstützt my envkeine --Abgrenzung und unternimmt keine env -i FOO=bar -- envVersuche, einen Befehl mit dem Namen auszuführen --.
Antak
@antak Das sollte env -i -- FOO=bar enveigentlich sein. Mein Fehler. Nicht, dass das --nützlich wäre, denn das Folgende beginnt nicht mit -.
Gilles
Wusste nicht, dass man immer in localhost einsteigen kann, das ist irgendwie komisch. Was ist der Anwendungsfall dort.
Edgar Aroutiounian
@EdgarAroutiounian Sie können SSH an localhost senden, wenn ein SSH-Server ausgeführt wird. Warum sollten Programmierer versuchen, es zu verbieten?
Gilles
4

Während die akzeptierte Antwort korrekt ist, möchten Sie normalerweise Folgendes tun:

env -i bash -l -c "printenv; and any other commands"

Dadurch erhalten Sie eine nackte, aber funktionierende Bash (genau wie bei der Anmeldung im nicht interaktiven Modus). Dies stellt zum Beispiel die Sprache, Zeitzone, HOME usw. ein.

Marcin Raczkowski
quelle
Das funktioniert nicht ganz, weil env -iClears HOME, bash -ldh Ihr .bash_profileusw. nicht finden können . Wenn Sie eine Shell möchten, die derjenigen entspricht, die Sie bei einem neuen Login erhalten würden, müssen Sie zuerst eine zusätzliche Indirektion festlegen HOME.
Elliott Slaughter
Siehe diese Antwort: unix.stackexchange.com/a/451389/157340
Elliott Slaughter
1

Das Problem mit den meisten Antworten hier ist, dass es sich env -iklärt HOME. Selbst wenn Sie bash -lvon innen laufen , wird es Ihr .bash_profileusw. nicht lesen . Wenn Sie nach einer Shell suchen, die sich so verhält, als hätten Sie sich gerade neu angemeldet, sind Sie würde dies stattdessen wollen:

env -i HOME="$HOME" bash -l -c 'your_command'

Beispiel:

$ export ABC=123
$ env -i HOME="$HOME" bash -l -c 'env' | grep ABC
$ env HOME="$HOME" bash -l -c 'env' | grep ABC
ABC=123
Elliott Slaughter
quelle
1
Beachten Sie, dass eine Login- bashShell ausgeführt wird .bash_loginoder .bash_profile. Verwenden Sie ein Verzeichnis, das diese Dateien nicht enthält --noprofile, oder legen Sie es fest HOME, um eine saubere Umgebung zu erhalten . Ich nehme an, es hängt davon ab, was Sie mit "sauber" meinen.
Kusalananda
1
Ja, wenn Sie eine Shell wünschen, in der buchstäblich nichts enthalten ist, folgen Sie einfach der ursprünglichen Antwort und tun Sie dies env -i bash -c .... Diese Antwort ist speziell, wenn Sie eine Shell möchten, die aussieht, als hätten Sie sich gerade neu auf dem Computer angemeldet.
Elliott Slaughter
0

Um den Kommentar von balki zu beantworten (und dabei meine eigene Frage zu beantworten :-):

% echo Environment in calling shell: vars: $(env |wc -l); echo; ./du; echo; cat du
Environment in calling shell: vars: 43

==> This is the environment: vars: 5
PATH="$PATH"
PWD=/Users/nick
SHLVL=1
SOMETHING_TO_KEEP="$USER"
_=/usr/bin/env
==> The end.

#!/usr/bin/env -i SOMETHING_TO_KEEP="$USER" PATH="$PATH" /bin/sh

echo "==> This is the environment: vars:" $(/usr/bin/env | /usr/bin/wc -l)
/usr/bin/env
echo "==> The end."
Coroos
quelle
Wenn ich das in meiner shebang-Zeile in CentOS 7.6 versuche, erhalte ich diesen Fehler von env:/usr/bin/env: invalid option -- ' ' Try '/usr/bin/env --help' for more information.
ScottJ
Wenn ich das Skript ändere, um das lange Argument zu verwenden, --ignore-environment/usr/bin/env: unrecognized option '--ignore-environment SOMETHING_TO_KEEP="$USER" PATH="$PATH" /bin/sh' Try '/usr/bin/env --help' for more information.
erhalte