bash不会在远程ssh命令上加载节点

时间:2022-12-30 14:25:52

Excuse me if the subject is vague, but I tried to describe my problem to the best of my possibilities. I have my raspberry pi which I want to deploy to using codeship. Rsyncing the files works perfectly, but when I am to restart my application using pm2 my problem occurs.

如果主题含糊不清,请原谅我,但我试图尽可能地描述我的问题。我有我的树莓派,我想部署使用代码。 Rsyncing文件工作正常,但当我使用pm2重新启动我的应用程序时,我的问题出现了。

I have installed node and pm2 using the node version manager NVM.

我已经使用节点版本管理器NVM安装了node和pm2。

ssh pi@server.com 'source /home/pi/.bashrc; cd project; pm2 restart app.js -x -- --prod'0 min 3 sec
bash: pm2: command not found

I have even added:

我甚至添加了:

shopt -s expand_aliases in the bottom of my bashrc but it doesn't help.

shopt -s expand_aliases在我的bashrc底部,但它没有帮助。

How can I make it restart my application after I have done a deploy? Thanks in advance for your sage advice and better wisdom!

完成部署后如何让它重新启动我的应用程序?在此先感谢您的圣人建议和更好的智慧!

EDIT 1: My .bashrc http://pastie.org/10529200 My $PATH: /home/pi/.nvm/versions/node/v4.2.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games

编辑1:我的.bashrc http://pastie.org/10529200 My $ PATH:/home/pi/.nvm/versions/node/v4.2.0/bin:/usr/local/sbin:/usr/local/bin :/ usr / sbin目录:在/ usr / bin中:/ sbin目录:/ bin中:在/ usr /本地/游戏:在/ usr /游戏

EDIT 2: I added /home/pi/.nvm/versions/node/v4.2.0/bin/pm2 which is the full path to pm2 and now I get the following error: /usr/bin/env: node: No such file or directory

编辑2:我添加了/home/pi/.nvm/versions/node/v4.2.0/bin/pm2这是pm2的完整路径,现在我收到以下错误:/ usr / bin / env:node:没有这样的文件或目录

It seems that even if I provide the full path, node isn't executed.

看来即使我提供完整路径,也不会执行节点。

4 个解决方案

#1


9  

I think the problem is the misinterpretation that the shell executing node has a full environment like an interactive ssh session does. Most likely this is not the case.

我认为问题是shell执行节点具有像交互式ssh会话那样的完整环境的错误解释。最有可能的情况并非如此。

When a SSH session spawns a shell it goes through a lot of gyrations to build an environment suitable to work with interactively. Things like inheriting from the login process, reading /etc/profile, reading ~/.profile. But in the cases where your executing bash directly this isn't always guaranteed. In fact the $PATH might be completely empty.

当SSH会话产生一个shell时,它经历了很多旋转,以构建一个适合交互式工作的环境。比如继承登录过程,读取/ etc / profile,读取〜/ .profile。但是在直接执行bash的情况下,这并不总能得到保证。事实上,$ PATH可能完全是空的。

When /usr/bin/env node executes it looks for node in your $PATH which in a non-interactive shell could be anything or empty.

当/ usr / bin / env节点执行时,它会查找$ PATH中的节点,该节点在非交互式shell中可以是任何或空的。

Most systems have a default PATH=/bin:/usr/bin typically /usr/local/bin is not included in the default environment.

大多数系统都有默认的PATH = / bin:/ usr / bin通常/ usr / local / bin不包含在默认环境中。

You could attempt to force a login with ssh using ssh … '/bin/bash -l -c "…"'.

您可以尝试使用ssh强制登录ssh ...'/ bin / bash -l -c“...”'。

You can also write a specialized script on the server that knows how the environment should be when executed outside of an interactive shell:

您还可以在服务器上编写专用脚本,该脚本在交互式shell外部执行时知道环境应该如何:

#!/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

Then call it through ssh: ssh … '/usr/local/bin/my_script.sh'.

然后通过ssh:ssh ...'/usr/local/bin/my_script.sh'调用它。

Beyond these ideas I don't see how to help further.

除了这些想法,我不知道如何进一步提供帮助。

#2


6  

Like Sukima said, the likelihood is that this is due to an environment issue - SSH'ing into a server does not set up a full environment. You can, however, get around much of this by simply calling /etc/profile yourself at the start of your command using the . operator (which is the same as the "source" command):

就像Sukima所说,可能是因为环境问题 - SSH进入服务器并没有建立一个完整的环境。但是,你可以通过简单地在命令开始时使用/来调用/ etc / profile来解决大部分问题。 operator(与“source”命令相同):

ssh pi@server.com '. /etc/profile ; cd project; pm2 restart app.js -x -- --prod'

/etc/profile should itself be set up to call the .bashrc of the relevant user, which is why I have removed that part. I used to have to do this quite a lot for quick proof-of-concept scripts at a previous workplace. I don't know if it would be considered a nasty hack for a more permanent script, but it certainly works, and would require minimal modification to your existing script should that be an issue.

/ etc / profile本身应设置为调用相关用户的.bashrc,这就是我删除该部分的原因。在以前的工作场所,我曾经非常需要为快速概念验证脚本做很多事情。我不知道它是否会被认为是一个更加永久的脚本的讨厌的黑客,但它确实有效,并且如果这是一个问题,将需要对现有脚本进行最少的修改。

#3


4  

Try:

尝试:

ssh pi@server.com 'bash -l -c "source /home/pi/.bashrc; cd project; pm2 restart app.js -x -- --prod"'

#4


1  

What worked for me was adding this to my .bash_profile:

对我有用的是将其添加到我的.bash_profile:

if [ -f ~/.bashrc ]; then
  . ~/.bashrc
fi

Source: https://*.com/a/820533/1824444

资料来源:https://*.com/a/820533/1824444

#1


9  

I think the problem is the misinterpretation that the shell executing node has a full environment like an interactive ssh session does. Most likely this is not the case.

我认为问题是shell执行节点具有像交互式ssh会话那样的完整环境的错误解释。最有可能的情况并非如此。

When a SSH session spawns a shell it goes through a lot of gyrations to build an environment suitable to work with interactively. Things like inheriting from the login process, reading /etc/profile, reading ~/.profile. But in the cases where your executing bash directly this isn't always guaranteed. In fact the $PATH might be completely empty.

当SSH会话产生一个shell时,它经历了很多旋转,以构建一个适合交互式工作的环境。比如继承登录过程,读取/ etc / profile,读取〜/ .profile。但是在直接执行bash的情况下,这并不总能得到保证。事实上,$ PATH可能完全是空的。

When /usr/bin/env node executes it looks for node in your $PATH which in a non-interactive shell could be anything or empty.

当/ usr / bin / env节点执行时,它会查找$ PATH中的节点,该节点在非交互式shell中可以是任何或空的。

Most systems have a default PATH=/bin:/usr/bin typically /usr/local/bin is not included in the default environment.

大多数系统都有默认的PATH = / bin:/ usr / bin通常/ usr / local / bin不包含在默认环境中。

You could attempt to force a login with ssh using ssh … '/bin/bash -l -c "…"'.

您可以尝试使用ssh强制登录ssh ...'/ bin / bash -l -c“...”'。

You can also write a specialized script on the server that knows how the environment should be when executed outside of an interactive shell:

您还可以在服务器上编写专用脚本,该脚本在交互式shell外部执行时知道环境应该如何:

#!/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

Then call it through ssh: ssh … '/usr/local/bin/my_script.sh'.

然后通过ssh:ssh ...'/usr/local/bin/my_script.sh'调用它。

Beyond these ideas I don't see how to help further.

除了这些想法,我不知道如何进一步提供帮助。

#2


6  

Like Sukima said, the likelihood is that this is due to an environment issue - SSH'ing into a server does not set up a full environment. You can, however, get around much of this by simply calling /etc/profile yourself at the start of your command using the . operator (which is the same as the "source" command):

就像Sukima所说,可能是因为环境问题 - SSH进入服务器并没有建立一个完整的环境。但是,你可以通过简单地在命令开始时使用/来调用/ etc / profile来解决大部分问题。 operator(与“source”命令相同):

ssh pi@server.com '. /etc/profile ; cd project; pm2 restart app.js -x -- --prod'

/etc/profile should itself be set up to call the .bashrc of the relevant user, which is why I have removed that part. I used to have to do this quite a lot for quick proof-of-concept scripts at a previous workplace. I don't know if it would be considered a nasty hack for a more permanent script, but it certainly works, and would require minimal modification to your existing script should that be an issue.

/ etc / profile本身应设置为调用相关用户的.bashrc,这就是我删除该部分的原因。在以前的工作场所,我曾经非常需要为快速概念验证脚本做很多事情。我不知道它是否会被认为是一个更加永久的脚本的讨厌的黑客,但它确实有效,并且如果这是一个问题,将需要对现有脚本进行最少的修改。

#3


4  

Try:

尝试:

ssh pi@server.com 'bash -l -c "source /home/pi/.bashrc; cd project; pm2 restart app.js -x -- --prod"'

#4


1  

What worked for me was adding this to my .bash_profile:

对我有用的是将其添加到我的.bash_profile:

if [ -f ~/.bashrc ]; then
  . ~/.bashrc
fi

Source: https://*.com/a/820533/1824444

资料来源:https://*.com/a/820533/1824444