Je pense que le problème est l'interprétation erronée selon laquelle le nœud d'exécution du shell a un environnement complet comme le fait une session ssh interactive. Ce n'est probablement pas le cas.
Lorsqu'une session SSH génère un shell, elle passe par de nombreuses girations pour créer un environnement adapté au travail interactif. Des choses comme hériter du processus de connexion, lire /etc/profile
, lecture ~/.profile
. Mais dans les cas où votre bash s'exécute directement, cela n'est pas toujours garanti. En fait le $PATH
peut être complètement vide.
Quand /usr/bin/env node
exécute il recherche le nœud dans votre $PATH
qui, dans un shell non interactif, pourrait être n'importe quoi ou vide.
La plupart des systèmes ont un PATH=/bin:/usr/bin
par défaut généralement /usr/local/bin
n'est pas inclus dans l'environnement par défaut.
Vous pouvez essayer de forcer une connexion avec ssh en utilisant ssh … '/bin/bash -l -c "…"'
.
Vous pouvez également écrire un script spécialisé sur le serveur qui sait comment l'environnement doit être lorsqu'il est exécuté en dehors d'un shell interactif :
#!/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
Appelez-le ensuite via ssh :ssh … '/usr/local/bin/my_script.sh'
.
Au-delà de ces idées, je ne vois pas comment aider davantage.
Comme l'a dit Sukima, il est probable que cela soit dû à un problème d'environnement - le SSH sur un serveur ne configure pas un environnement complet. Vous pouvez cependant contourner une grande partie de cela en appelant simplement /etc/profile vous-même au début de votre commande en utilisant le . opérateur (qui est le même que la commande "source") :
ssh [email protected] '. /etc/profile ; cd project; pm2 restart app.js -x -- --prod'
/etc/profile doit lui-même être configuré pour appeler le .bashrc de l'utilisateur concerné, c'est pourquoi j'ai supprimé cette partie. J'avais l'habitude de le faire beaucoup pour des scripts de preuve de concept rapides sur un lieu de travail précédent. Je ne sais pas si cela serait considéré comme un mauvais piratage pour un script plus permanent, mais cela fonctionne certainement et nécessiterait une modification minimale de votre script existant si cela posait un problème.
Essayez :
ssh [email protected] 'bash -l -c "source /home/pi/.bashrc; cd project; pm2 restart app.js -x -- --prod"'