問題は、対話型の ssh セッションのようにシェル実行ノードに完全な環境があるという誤解だと思います。ほとんどの場合、そうではありません。
SSH セッションがシェルを生成するとき、インタラクティブに作業するのに適した環境を構築するために、シェルは多くの回転を経ます。ログインプロセスからの継承、読み取り /etc/profile
など 、読み取り ~/.profile
.ただし、bash を直接実行する場合、これは常に保証されるわけではありません。実際には $PATH
完全に空かもしれません。
/usr/bin/env node
のとき $PATH
でノードを探します 非対話型シェルでは、これは何でもか空の可能性があります。
ほとんどのシステムにはデフォルトの PATH=/bin:/usr/bin
があります 通常 /usr/local/bin
デフォルト環境には含まれていません。
ssh … '/bin/bash -l -c "…"'
を使用して ssh で強制的にログインを試みることができます .
対話型シェルの外で実行されたときに環境がどうあるべきかを知る特殊なスクリプトをサーバー上に書くこともできます:
#!/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
次に、ssh 経由で呼び出します:ssh … '/usr/local/bin/my_script.sh'
.
これらのアイデアを超えて、さらに支援する方法がわかりません。
スキマが言ったように、これは環境の問題が原因である可能性があります.SSHでサーバーに接続しても完全な環境は設定されません.ただし、コマンドの開始時に . operator (「source」コマンドと同じ):
ssh [email protected] '. /etc/profile ; cd project; pm2 restart app.js -x -- --prod'
/etc/profile 自体は、関連するユーザーの .bashrc を呼び出すように設定する必要があるため、その部分を削除しました。以前の職場では、概念実証スクリプトを迅速に作成するために、これをかなり頻繁に行う必要がありました。より恒久的なスクリプトの厄介なハックと見なされるかどうかはわかりませんが、確かに機能し、問題が発生した場合でも既存のスクリプトを最小限に変更する必要があります.
試してみてください:
ssh [email protected] 'bash -l -c "source /home/pi/.bashrc; cd project; pm2 restart app.js -x -- --prod"'