· via Hacker News – Front Page (native)
Quoted tilde in shell PATH entries silently adds a literal ~ directory instead of $HOME/bin
A quoted tilde in export PATH lines never expands to your home directory, leaving a relative ./~ entry on your PATH that writable directories can exploit — as one agent sandbox's warning revealed.

A post on disconnect3d.pl, picked up on the Hacker News front page, warns that one of the most common lines in shell configuration files does something quite different from what its author intends. Writing export PATH="$PATH:~/.local/bin/" in .bashrc or .zshrc does not add your home directory's local bin folder to the command search path. It adds an entry containing a literal tilde character — a relative path resolved against whatever directory the shell happens to be in.
The author ran into the issue while experimenting with nono, a sandboxing tool for AI agents. The tool warned that a PATH entry was writable from inside the sandbox, and the entry it flagged was ~/.local/bin/, which looked suspicious, since a sandbox should not be able to write to the user's home directory.
Why the tilde survives
The culprit is quoting. According to the Bash documentation cited in the post, tilde expansion applies only when a tilde appears unquoted at the start of a word, and Bash additionally expands unquoted tildes in variable assignments when they immediately follow an = or a :. Inside double quotes, the tilde is an ordinary character.
The result is a PATH entry spelled ~/.local/bin/. Because it does not begin with a slash, the shell treats it as relative — effectively ./~/.local/bin/ — and resolves it against the current working directory whenever a command is looked up.
A short demonstration
To prove the point, the author created a directory tree literally named ~/.local/bin inside an empty working directory, compiled a small C program called kek into it, and invoked it as PATH="~/.local/bin/" kek. The program ran and printed its greeting, having been found in the literal tilde directory; the user's home directory played no part in the lookup.
How to check and fix it
A quick test:
sh echo "$PATH" | tr ':' '\n' | grep '~'
Any output means the misconfiguration is present. The fix is to open .bashrc, .zshrc or .profile and replace the tilde with $HOME:
sh export PATH="$PATH:$HOME/.local/bin/"
The author points out that the unquoted form, export PATH=$PATH:~/.local/bin, does expand correctly in both Bash and Zsh, because those shells perform tilde expansion in assignments after = and after each :. He still calls it fragile — a space anywhere in the value would break the assignment — and recommends the quoted $HOME form as the reliable option.
He also credits nono for surfacing the problem in the first place, while noting that its warning could explain the issue more clearly; a pull request to improve the message is on the way, he writes.
Why it matters
Adding ~/.local/bin to PATH is standard advice, repeated wherever people set up pip --user or other per-user tooling, so the quoted-tilde variant almost certainly lives in many dotfiles. The failure is completely silent: the shell never errors, and the intended directory simply never gets searched.
The security consequence is what elevates this beyond a cosmetic bug. A relative PATH entry turns every writable directory into a potential command-injection point. Anything that can create a folder named ~ with a .local/bin subtree inside it — an AI coding agent with write access to a project directory, a cloned repository, or a shared writable location — can plant executables that the shell will run whenever a command is not found earlier in PATH. If the entry were prepended rather than appended, it would shadow real system commands outright. Sandboxing tools like nono catch this by comparing PATH entries against locations the sandbox can write, which is exactly how this case came to light.
The general lesson is that tilde expansion is a convenience of unquoted shell input, not a property of variables. Inside quotes, always use $HOME.
- #shell
- #bash
- #zsh
- #security
- #path