Saya pikir masalahnya adalah salah tafsir bahwa node pelaksana shell memiliki lingkungan penuh seperti sesi ssh interaktif. Kemungkinan besar bukan itu masalahnya.
Saat sesi SSH memunculkan sebuah shell, ia melewati banyak putaran untuk membangun lingkungan yang cocok untuk bekerja secara interaktif. Hal-hal seperti mewarisi dari proses login, membaca /etc/profile
, membaca ~/.profile
. Tetapi dalam kasus di mana Anda mengeksekusi bash secara langsung, ini tidak selalu dijamin. Sebenarnya $PATH
mungkin benar-benar kosong.
Ketika /usr/bin/env node
mengeksekusinya mencari simpul di $PATH
Anda yang dalam shell non-interaktif bisa berupa apa saja atau kosong.
Sebagian besar sistem memiliki PATH=/bin:/usr/bin
default biasanya /usr/local/bin
tidak termasuk dalam lingkungan default.
Anda dapat mencoba memaksa login dengan ssh menggunakan ssh … '/bin/bash -l -c "…"'
.
Anda juga dapat menulis skrip khusus di server yang mengetahui bagaimana seharusnya lingkungan saat dijalankan di luar shell interaktif:
#!/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
Kemudian panggil melalui ssh:ssh … '/usr/local/bin/my_script.sh'
.
Di luar ide ini, saya tidak melihat cara untuk membantu lebih lanjut.
Seperti kata Sukima, kemungkinan besar ini karena masalah lingkungan - SSH'ing ke server tidak menyiapkan lingkungan penuh. Namun, Anda dapat mengatasi sebagian besar dari ini hanya dengan memanggil /etc/profile sendiri di awal perintah Anda menggunakan . operator (yang sama dengan perintah "sumber"):
ssh [email protected] '. /etc/profile ; cd project; pm2 restart app.js -x -- --prod'
/etc/profile itu sendiri harus diatur untuk memanggil .bashrc dari pengguna yang relevan, itulah sebabnya saya telah menghapus bagian itu. Saya dulu harus melakukan ini cukup banyak untuk skrip proof-of-concept cepat di tempat kerja sebelumnya. Saya tidak tahu apakah ini akan dianggap peretasan yang buruk untuk skrip yang lebih permanen, tetapi pasti berhasil, dan akan membutuhkan sedikit modifikasi pada skrip Anda yang ada jika itu menjadi masalah.
Coba:
ssh [email protected] 'bash -l -c "source /home/pi/.bashrc; cd project; pm2 restart app.js -x -- --prod"'