
Ich muss einen SSH-Sudo-Befehl ausführen.
Der Befehl lautet wie folgt:
ssh -i keyfile [email protected] 'sh -v /opt/dir/script'
Das Skript enthält Folgendes:
sudo -E node some.js
der Grund, warum ich das Argument -E verwende, ist, dass der Befehl von BenutzerA ausgeführt wirdUNDDer gestartete Prozess muss Definitionen laden von
/user/userA/.bashrc
der obige Befehl lädt NICHT die Variablen, die in
/user/userA/.bashrc
es läuft tatsächlich so, als ob -E nichts bewirkt. Das heißt, alle Variablen werden als undefiniert angezeigt.
Wenn ich mich interaktiv als BenutzerA bei der Remote-Maschine anmelde und denselben Befehl ausführe, nämlich
sudo -E node some.js
die Variablen werden korrekt geladen und ich sehe das erwartete Verhalten.
Sieht jemand, was ich anders machen muss?
Antwort1
Sie erwarten, dass die Shell eine Quelle ~/.bashrc
ist, daher nehme ich an, dass es sich bei der Shell um Bash handelt.
Twist Nummer 1: Der SSH-Server übergibt den Shell-Code an eine nicht interaktive Shell. Nicht interaktive Bashnichtlesen ~/.bashrc
.
Twist Nummer 2: Bash versucht zu bestimmen, wann es mit seiner Standardeingabe ausgeführt wird, die mit einer Netzwerkverbindung verbunden ist, wie wenn es von einem SSH-Server ausgeführt wird. Wenn Bash feststellt, dass es auf diese Weise ausgeführt wird,tutBefehle von lesen und ausführen ~/.bashrc
.
Twist Nummer 3: In vielen Distributionen (einschließlich Ubuntu) ist die Standard-(Skelett-)~/.bashrc
mit Code, der zurückkehrt, wenn die Shell nicht interaktiv ist. Tatsächlich ist der Rest der Dateinicht bezogen.
Ich vermute, in Ihrem Fall werden die relevanten Umgebungsvariablen nach diesem Codeabschnitt definiert. Der Code könnte folgendermaßen aussehen:
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
Eine einfache Lösung besteht darin, die Aufgaben so zu verschieben, dass sieVordieser Code. Wenn Sie Befehle verschieben möchten, die mehr tun (z. B.echo
etwas ausführen), dann seien Sie sehr vorsichtig, da Sie dadurch möglicherweise Remote-Dateiübertragungen unterbrechen. Lesen SieWarum tutbashrc
geprüft, ob die aktuelle Shell interaktiv ist?Wenn es nur um Variablen geht, sollte es sicher sein.
Im Allgemeinen die Umweltsollte definiert werden in~/.profile
anstatt in ~/.bashrc
, aber wenn Sie die Zuweisungen nach verschieben würden ~/.profile
, würden Sie Folgendes erleben:~/.profile
wird bei Verwendung von SSH nicht geladen. Es ist nicht unvernünftig, sie ~/.bashrc
dann dabei zu haben.
Alternativ können Sie sie in einer separaten Datei ablegen, z. B. ~/.special_env
, und die Datei von ~/.bashrc
oder ~/.profile
oder was auch immer beziehen. Der Vorteil ist, dass Sie die Datei bei Bedarf unabhängig von Eigenheiten und Wendungen beziehen können:
ssh -i keyfile [email protected] '. ~/.special_env; sh -v /opt/dir/script'