Manjaro Update 导致的脚本错误 (不良习惯)

之前 tmux 一打开就会出现一段 errout:

/etc/profile.d/perlbin.sh:10: command not found: append_path

今天有空刚好 debug 一下这个问题.

调查调用链

首先从日志得知, 以这个 /etc/profile.d/perlbin.sh 文件为线索入手.
看起来像是 append_path 这个 command 找不到, 从目录可知应该是被 /etc/profile 调用 :

/etc/profile:

# Load profiles from /etc/profile.d
if test -d /etc/profile.d/; then
for profile in /etc/profile.d/*.sh; do
test -r "$profile" && . "$profile"
done
unset profile
fi

而这段脚本前, 还有这么一段:

appendpath () {
case ":$PATH:" in
*:"$1":*)
;;
*)
PATH="${PATH:+$PATH:}$1"
esac
}

appendpath '/usr/local/sbin'
appendpath '/usr/local/bin'
appendpath '/usr/bin'
unset appendpath

appendpath 是一个 function, 但是又被 unset 了, 看起来莫名其妙对吧.

为什么是这样, 不应该有这么低级的 bug 呀.

pacnew

在检查 /etc/profile 时, 发现了还有一个文件 /etc/profile.pacnew.
.pacnew 文件, 从 Arch 的文档 Pacnew_and_Pacsave 可知:

A .pacnew file may be created during a package upgrade (pacman -Syu, pacman -Su or pacman -U) to avoid overwriting a file which already exists and was previously modified by the user. When this happens, a message like the following will appear in the output of pacman:
warning: /etc/pam.d/usermod installed as /etc/pam.d/usermod.pacnew

也就是说, 我之前编辑过 /etc/profile 文件, 所以当我更新系统时,
/etc/profile 不会被更新, 新的 /etc/profile 文件会被安装到 /etc/profile.pacnew 文件.

diff 这两个文件可知:

unset append_path 这段脚本在新版本的 update 中本应被删除的, 因此导致了这个问题的发生.

解决

最佳方案是把 custom 代码移到其他地方去, 这样会更加优雅,
避免系统更新时再次发生这个问题 (这个问题可能会很严重).

这里我把自己的脚本新建了一个文件, 在 /etc/profile.d/ 目录之下, 这样更优雅和安全.

在 Reddit 上大家也碰到类似的问题.

https://www.reddit.com/r/archlinux/comments/j0zly6/bash_append_path_command_not_found/