The tilde in your PATH may not be your home
Translated by a model; the original is in Russian.
While experimenting with nono, an agent-sandboxing tool, the author got a suspicious warning: the sandbox could write to the PATH entry ~/.local/bin/. Digging in revealed a long-standing shell gotcha worth knowing for anyone who edits their .bashrc or .zshrc.
The catch
A line like
export PATH="$PATH:~/.local/bin/"
will not turn the tilde into your home directory. Tilde-to-$HOME expansion happens only for unquoted tildes, and inside double quotes the tilde stays literal. So PATH ends up with ./~/.local/bin/ — a relative path to a directory literally named «tilde» in the current folder — instead of /home/<user>/.local/bin/.
The bash docs back this up: a tilde-prefix is expanded when a word begins with an unquoted tilde, including right after an = or a : in a variable assignment. The operative word is unquoted.
Why it is unsafe
The author gives a vivid demo. He creates ./~/.local/bin/, drops a compiled binary kek into it, then runs PATH="~/.local/bin/" kek — and the program is found and executed. The home directory is never touched: the shell located the executable in a subdirectory of the current folder.
Hence the sandbox's alarm: if a PATH entry effectively points at the current directory, anyone who can write there can slip you an executable to run.
How to check and fix
A quick check:
echo "$PATH" | grep -- '~'
or, to see each entry on its own line:
echo "$PATH" | tr ':' '\n' | grep '~'
If anything prints, open .bashrc, .zshrc or .profile and replace the tilde with $HOME:
export PATH="$PATH:$HOME/.local/bin/"
Amusingly, the unquoted form — export PATH=$PATH:~/.local/bin — does work in bash and zsh, because tilde expansion also runs in assignments after = and after each :. But leaning on that is fragile: a single stray space will break the assignment. The author also credited the nono tool for flagging the issue — and promised a PR to make its warning a bit more verbose.
Source: Hacker News
Comments
Sign in, to comment.