Ubuntu 22.04 上写了个部署脚本,sudo 执行时里面调 java 报 command not found,手动跑没事,sudo -l 能看到 NOPASSWD,sudo env 里 PATH 只剩 /usr/bin:/bin。
一开始怀疑是「java 装在 /usr/local/jdk/bin,不在 secure_path 列表里」,查了一圈,方向不对。
把日志和配置对完,能解释这个现象的基本就这几处。sudo 默认 env_reset,把当前 shell 的 PATH 重置成默认值。另一种情况是sudoers 里的 secure_path 写死了,脚本里 export 的 PATH 被覆盖。
另外,脚本用 sh 执行,shebang 和环境变量都没继承下来。
先确认 sudo 下的环境
sudo env | grep -E 'PATH|JAVA_HOME'
然后查看 secure_path 的设置
sudo grep -rn 'secure_path' /etc/sudoers /etc/sudoers.d/
接着在 sudoers 里补上安装路径
echo 'Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/jdk/bin"' > /etc/sudoers.d/path && visudo -c
脚本里显式声明解释器和路径
sudo -E env PATH=/usr/local/jdk/bin:$PATH /bin/bash deploy.sh
白天有业务在跑,能验证的部分都压到了晚上做。
当时还开着另一个排查窗口,两边日志对照着看才定位到。
同一份数据我导出了两份,一份留底,一份拿来试。
改完先别撤,确认这几项。sudo 执行部署脚本能找到 java,java -version 输出正常,脚本退出码为 0。
这里还有个坑。改 sudoers 必须用 visudo 校验,写坏了会把 sudo 一起锁死;临时 sudo -E 能保环境,但脚本里写绝对路径更可靠。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。
