跳到正文
Hacker News 熱門(buzzing.cc 中文翻譯)·· 2 小時前AI 評分55

PATH 中的波浪號未必會展開為 HOME 路徑

PATH 中的波浪号可能并非您的 HOME

AI 導讀

文章指出,將 `~/.local/bin/` 放在引號內加入 PATH 時,波浪號不會展開成家目錄,可能令 PATH 指向 `./~/.local/bin/`。可改用 `$HOME/.local/bin/`,並以 `echo " $PATH " | grep -- '~'` 搜尋 PATH 中是否仍有波浪號;未加引號的寫法在 Bash 和 Zsh 可運作,但空格可能令變數指派失效。

正文

I was playing with the nono agent sandboxing tool and it greeted me with a warning: PATH entries the sandbox can write to: ~/.local/bin/ which looked suspicious.

nono warning about PATH entries the sandbox can write to

In other words, doing this in your ~/.bashrc or ~/.zshrc:

export PATH="$PATH:~/.local/bin/"

will not expand the ~ (tilde) into the home path (or $HOME) as the tilde to home expansion happens only in unquoted inputs, as also the bash documentation says:

If a word begins with an unquoted tilde character (‘~’), all of the characters up to the first unquoted slash (…) are considered a tilde-prefix. (…)

Bash checks each variable assignment for unquoted tilde-prefixes immediately following a ‘:’ or the first ‘=’, and performs tilde expansion in these cases. (…)

So instead of having /home/<user>/.local/bin/ added to PATH we end up with ./~/.local/bin/ added to PATH.

And to fix this, we can do this:

export PATH="$PATH:$HOME/.local/bin/"

Note that the unquoted version export PATH=$PATH:~/.local/bin actually works in Bash and Zsh, because tilde expansion is also performed in variable assignments after = and after each :. But relying on that is fragile as for example, a whitespace will break the variable assignment.

The problem can also be seen here:

$ 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

Demo showing that a literal tilde in PATH resolves to a ./~/ directory in the current working directory

As we can see, the kek binary was found and executed from ./~/.local/bin/ — the home directory was never involved.

Check your PATH

You can quickly check whether you have this problem with:

$ echo "$PATH" | grep -- '~'

or, to see each entry on its own line:

$ echo "$PATH" | tr ':' '\n' | grep '~'
~/.local/bin/

If it prints anything, go fix your .bashrc/.zshrc/.profile and replace the ~ with $HOME :).

Btw, kudos to the nono tool for warning about this - even though the warning could be more verbose (PR incoming).

來源:Hacker News 熱門(buzzing.cc 中文翻譯) · disconnect3d.pl