Ich denke, das Problem ist die Fehlinterpretation, dass der Shell-Ausführungsknoten eine vollständige Umgebung hat, wie es eine interaktive SSH-Sitzung tut. Höchstwahrscheinlich ist dies nicht der Fall.
Wenn eine SSH-Sitzung eine Shell hervorbringt, durchläuft sie viele Drehungen, um eine Umgebung aufzubauen, die für die interaktive Arbeit geeignet ist. Dinge wie das Erben vom Anmeldeprozess, das Lesen von /etc/profile
, liest ~/.profile
. Aber in den Fällen, in denen Sie bash direkt ausführen, ist dies nicht immer garantiert. Genauer gesagt die $PATH
möglicherweise vollständig leer.
Wenn /usr/bin/env node
ausführt, sucht es nach Knoten in Ihrem $PATH
was in einer nicht interaktiven Shell irgendetwas oder leer sein könnte.
Die meisten Systeme haben einen Standardwert PATH=/bin:/usr/bin
normalerweise /usr/local/bin
ist nicht in der Standardumgebung enthalten.
Sie könnten versuchen, eine Anmeldung mit ssh mit ssh … '/bin/bash -l -c "…"'
zu erzwingen .
Sie können auch ein spezialisiertes Skript auf dem Server schreiben, das weiß, wie die Umgebung sein sollte, wenn es außerhalb einer interaktiven Shell ausgeführt wird:
#!/bin/bash
# Example shell script; filename: /usr/local/bin/my_script.sh
export PATH=$PATH:/usr/local/bin
export NODE_PATH=/usr/local/share/node
export USER=myuser
export HOME=/home/myuser
source $HOME/.nvm/nvm.sh
cd /usr/bin/share/my_script
nvm use 0.12
/usr/bin/env node ./script_name.js
Rufen Sie es dann über ssh auf:ssh … '/usr/local/bin/my_script.sh'
.
Über diese Ideen hinaus sehe ich nicht, wie ich weiter helfen kann.
Wie Sukima sagte, ist die Wahrscheinlichkeit, dass dies auf ein Umgebungsproblem zurückzuführen ist - SSH-Verbindung zu einem Server richtet keine vollständige Umgebung ein. Sie können jedoch vieles davon umgehen, indem Sie einfach selbst /etc/profile zu Beginn Ihres Befehls mit der . -Operator (der mit dem "source"-Befehl identisch ist):
ssh [email protected] '. /etc/profile ; cd project; pm2 restart app.js -x -- --prod'
/etc/profile sollte selbst so eingerichtet sein, dass es die .bashrc des entsprechenden Benutzers aufruft, weshalb ich diesen Teil entfernt habe. Früher musste ich das ziemlich oft für schnelle Proof-of-Concept-Skripte an einem früheren Arbeitsplatz machen. Ich weiß nicht, ob es ein fieser Hack für ein dauerhafteres Skript wäre, aber es funktioniert auf jeden Fall und würde nur minimale Änderungen an Ihrem bestehenden Skript erfordern, falls dies ein Problem sein sollte.
Versuchen Sie:
ssh [email protected] 'bash -l -c "source /home/pi/.bashrc; cd project; pm2 restart app.js -x -- --prod"'