【问题标题】:bash doesn't load node on remote ssh commandbash 不在远程 ssh 命令上加载节点
【发布时间】:2016-01-26 05:31:06
【问题描述】:

如果主题含糊不清,请原谅,但我已尽我所能描述我的问题。我有我的树莓派,我想使用 codeship 部署它。 Rsyncing 文件完美运行,但是当我使用 pm2 重新启动我的应用程序时,我的问题出现了。

我已经使用节点版本管理器 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

我什至添加了:

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

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

编辑 1:我的 .bashrc http://pastie.org/10529200 我的 $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

编辑 2:我添加了 /home/pi/.nvm/versions/node/v4.2.0/bin/pm2,这是 pm2 的完整路径,现在我收到以下错误:/usr/bin/env: node: No such file or directory

似乎即使我提供了完整路径,节点也没有被执行。

【问题讨论】:

  • pm2 是别名吗?如果是这样,它可能不会工作。你最好写一个脚本来处理这个并执行那个脚本。此外,您拥有的 ssh 命令假设您在 shell 中运行,但这不是一个好的假设。也许用"/bin/bash -c 'source ....'" 开始你的ssh 命令,这会导致上面的写脚本注释。最后,pm2 命令是否需要 tty?如果没有 -t 选项,则不会分配 tty。如果与您提供的示例不同,某些程序通常从交互式 shell 执行,则假定您有一个。
  • 感谢您的建议,遗憾的是它不会有任何区别。尝试了您的建议,甚至添加了/bin/bash -c "nvm use 4.2.0" 以尝试启用节点。不幸的是,它不起作用。 /bin/bash: nvm: command not found /bin/bash: pm2: command not found
  • 也许解决方案是简单地安装节点而不是使用像 nvm 这样的版本管理器?我更喜欢让 nvm 工作,因为它更容易切换版本。
  • 请显示您的/home/pi/.bashrc 文件和echo $PATH 输出。
  • Nvm 是一个函数,因此它必须在 shell 中获取。如果您使用bash -c 执行此操作,则它不起作用,因为一旦 -c 完成 bash shell 退出并且其中创建的任何环境都消失了。你有一个路径问题。 /bin/bash -c ’echo $PATH’ 看看缺少什么。 (单引号不是双引号)。

标签: linux node.js bash ssh codeship


【解决方案1】:

我认为问题在于对 shell 执行节点具有像交互式 ssh 会话一样的完整环境的误解。很可能不是这种情况。

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

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

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

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

您还可以在服务器上编写一个专门的脚本,该脚本知道在交互式 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

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

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

【讨论】:

  • 由于某种原因 bash -l -c 不适用于我的情况 - 我通过 nvm 安装了节点
【解决方案2】:

就像 Sukima 所说,这很可能是由于环境问题 - 通过 SSH 连接到服务器并没有设置完整的环境。但是,您可以通过在命令开始时使用 .运算符(与“源”命令相同):

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

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

【讨论】:

    【解决方案3】:

    试试:

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

    【讨论】:

    • 由于某种原因 bash -l -c 不适用于我的情况 - 我通过 nvm 安装了节点
    【解决方案4】:

    您应该通过“source”或点命令“.”启用一些环境值。这是一个例子。

    ssh pi@server.com '. /home/pi/.nvm/nvm.sh; cd project; pm2 restart app.js -x -- --prod'
    

    【讨论】:

      【解决方案5】:

      对我来说,我必须在安装 node and yarn using :nvm 时加载 :nvm

      要在ssh远程执行时加载:nvm,我们调用

      ssh :user@:host 'source ~/.nvm/nvm.sh; :other_commands_here'
      

      【讨论】:

      【解决方案6】:

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

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

      来源:https://stackoverflow.com/a/820533/1824444

      【讨论】:

        猜你喜欢
        • 2017-04-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-12
        • 2017-02-08
        相关资源
        最近更新 更多