export PATH="$PATH:~/.local/bin/"
不会将 ~(波浪号)展开为主目录路径(即 $HOME),因为波浪号到主目录的展开只会发生在未加引号的输入中,正如 bash 文档中所述:
如果一个单词以未加引号的波浪号字符(’~’)开头,那么直到第一个未加引号的斜杠(…)之前的所有字符都会被视为波浪号前缀。(…)
Bash 会检查每个变量赋值中紧跟在 ‘:’ 之后或第一个 ‘=’ 之后的未加引号波浪号前缀,并在这些情况下执行波浪号展开。(…)
因此,最终被添加到 PATH 中的不是 /home/<user>/.local/bin/,而是 ./~/.local/bin/。
export PATH="$PATH:$HOME/.local/bin/"
注意,不加引号的写法 export PATH=$PATH:~/.local/bin 在 Bash 和 Zsh 中实际上是可以工作的,因为变量赋值中在 ‘=’ 之后以及每个 ‘:’ 之后也会执行波浪号展开。但依赖这一点是脆弱的,例如,一个空格就会破坏变量赋值。
`$ ls -la
total 0
drwxr-xr-x@ 2 dc staff 64 Oct 2 13:37 .
drwxr-x—+ 105 dc staff 3360 Oct 2 13:37 ..
$ mkdir -p .//.local/bin/
$ printf ‘#include <stdio.h>\nint main() { puts(“hello”); }’>a.c; gcc a.c -o .//.local/bin/kek
$ PATH="/.local/bin/" kek
hello
$ tree -f
.
├── ./
│ └── .//.local
│ └── .//.local/bin
│ └── ./~/.local/bin/kek
└── ./a.c
4 directories, 2 files`

如我们所见,kek 二进制文件是从 ./~/.local/bin/ 中找到并执行的——主目录根本没有参与其中。
你可以用以下命令快速检查自己是否存在这个问题:
$ echo "$PATH" | grep -- '~'
或者,将每个条目单独显示在一行: