EC2新实例部署脚本npm/pm2命令找不到问题求助
这个问题的核心原因是:你通过ssh <<'ENDSSH'执行的远程命令属于非交互式非登录Shell,它不会自动加载~/.bashrc、~/.profile这类用户自定义的环境配置文件。而你手动安装的Node.js、npm、pm2,通常是通过这些配置文件把它们的路径添加到PATH环境变量中的——这就是为什么你手动SSH登录后能正常执行命令,但脚本里却提示“找不到”的原因。
下面给你几个可行的解决方案,按推荐程度排序:
方案1:在远程脚本开头加载环境配置文件
最简便的方法是在远程执行的脚本开头,手动加载你的环境配置文件,把Node相关的路径加入到当前Shell的PATH中。比如:
修改你脚本中的SSH远程执行部分:
ssh -i kp.pem ubuntu@xx.xx.xxx.xxx <<'ENDSSH' # 加载用户的bash配置,根据你的实际安装方式调整 source ~/.bashrc # 如果你是用nvm安装的Node.js,可能需要额外加载nvm的初始化脚本 # source ~/.nvm/nvm.sh cd api tar -xvf deployment.tar.gz rm deployment.tar.gz rm ormconfig.json mv ormconfig.prod.json ormconfig.json mv .env.prod .env mkdir -p uploads npm install pm2 stop api pm2 delete api pm2 install typescript pm2 link xxxxxxxxx yyyyyyyyyy pm2 update pm2 start src/index.ts --source-map-support --name=api --trace ENDSSH
提示:如果不确定要加载哪个文件,可以手动SSH登录后,执行
echo $PATH查看当前的PATH内容,对比非交互式Shell的默认PATH(可以通过ssh ubuntu@xx.xx.xxx.xxx 'echo $PATH'查看),找到差异的部分对应的配置文件。
方案2:使用命令的绝对路径
如果你不想加载配置文件,可以直接使用npm和pm2的绝对路径来执行命令。
首先手动SSH登录到新EC2实例,执行以下命令获取绝对路径:
which npm which pm2
比如得到的路径是/home/ubuntu/.nvm/versions/node/v18.17.0/bin/npm和/home/ubuntu/.nvm/versions/node/v18.17.0/bin/pm2,然后把脚本里的npm和pm2替换成这些绝对路径即可:
# 示例替换后的命令 /home/ubuntu/.nvm/versions/node/v18.17.0/bin/npm install /home/ubuntu/.nvm/versions/node/v18.17.0/bin/pm2 stop api # ... 其他pm2命令同理
方案3:手动指定PATH变量
在远程脚本开头直接把Node相关的路径添加到PATH中,比如:
ssh -i kp.pem ubuntu@xx.xx.xxx.xxx <<'ENDSSH' # 替换成你实际的Node安装路径 export PATH="/home/ubuntu/.nvm/versions/node/v18.17.0/bin:$PATH" cd api # ... 后续命令不变 ENDSSH
额外建议
如果后续还有类似的部署需求,你可以考虑通过系统级的包管理工具(比如apt)安装Node.js,这样Node的路径会默认加入到系统PATH中,非交互式Shell也能直接找到命令,避免这类环境变量问题。
内容的提问来源于stack exchange,提问作者George

