前言
上次我发表的这篇bug实在太雷了「
乡民篇-Github actions bash: npm: command not found when on ssh」,觉得网路上的方法无法让我真正了解问题的根本,所以我去挖掘真相,要跟大家来报告。
本系列目标
本系列所分享的bug实在太雷所以分2篇写解法,分别是我在网路上找到乡民写的类似问题的解法,以及后期我自行去挖掘真相后自己的解法
乡民篇-Github actions bash: npm: command not found when on ssh(本篇) 真相篇-Github actions bash: npm: command not found when on ssh环境:Ubuntu 18.04.4 LTS (GNU/Linux 5.3.0-1026-gcp x86_64)
原因是VPS上的系统环境变数的关係,SSH login角色不同会读不同的设定档案,我是参考这篇才得来灵感。同样是$env取得$PATH,同样是取得/usr/bin/env但是有没有加sudo值就有差异。login shell去SSH到VPS直接输入:
$env
如果是输入:
$sudo env
sudo的角色明显环境变数值短很多
安装nvm, npm
我按照这篇文章安装nvm及npm,然后他会在VPS的~/.bashrc帮我的$PATH增加npm指令路径
export NVM_DIR="/home/zen_master/.nvm"[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
装完后我的npm指令位置
which npm
原来npm执行指令在这儿:/home/zen_master/.nvm/versions/node/v12.14.0/bin/npm
重点来了,下面来了解什么情况$PATH才能加载~/.bashrc设定档的环境变数
/usr/bin/env环境变数的$PATH会因为加载设定档而不同值
设定档(~/.bashrc,/etc/bash.bashrc,/etc/profile,~/.profile)都可以设定增加环境变数值,因为SSH的login方式不同而加载不同的设定档,算算后,一共有四种组合:
login shell:取得 bash 时需要完整的登入流程的,就称为 login shellnon-login shell:取得 bash 接口的方法不需要重複登入的举动interactive 交互式Shell:提供了命令提示符可以输入命令non-interactive 非交互式Shell可以透过bash -c 「CMD指令」GitHub actions透过yml档案去做CI/CD指令在VPS上,这样的操作是「non-interactive + non-login shell」
四种默认配置组合
「non-interactive + non-login shell」会加载/etc/bash.bashrc
,~/.bashrc
「interactive + non-login shell」会加载/etc/bash.bashrc
,~/.bashrc
「interactive + login shell」会加载/etc/profile
,/etc/bash.bashrc
, ~/.profile
,~/.bashrc
「non-interactive + login shell」会加载/etc/profile
,/etc/bash.bashrc
, ~/.profile
,~/.bashrc
明明有读~/.bashrc为什么没有办法执行npm指令啊?
都确认有加载我要的
~/.bashrc
,那为什么还是会npm command not found
或/usr/bin/env: ‘node’: No such file or directory
逐一确认以下步骤
step1. 检查logout的时候npm一定也要执行在VPS背景中,我先绑定一个npm版本12.14.0nvm alias default 12.14.0
step2. 打开VPS上的~/.bashrc
查看里面这行有没有注解掉,如果没有注解这几行会影响当我们在使用non-interactive的时候SSH,程式就直接跳掉不会继续往下执行。
If not running interactively, don't do anything
上面这个注解就是说「如果跑在non-active的时候,就不做任何事了」(但我们就是需要啊!!)
成功
注意:不能加sudo喔,不然就又会是读取另一个角色的环境变数值