3

I've made a fresh install of Debian Wheezy, and installed zsh to it. Few days after, I've done a vanilla installation of TeX Live 2014, so I added the necessary binary paths to my $PATH. Now I started writing little scripts so I would like to put them somewhere easily accessible, that is ~/bin.

My path looks like this:

~/bin:/opt/texbin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games

Now, if I wanted to run something from TeX Live, it's easy:

% which pdflatex
/opt/texbin/pdflatex

No problem. But when I try running something from ~/bin, ...

% which hello_world
hello_world not found

So I double-checked:

% ls -l ~/bin
total 18
-rwxr-xr-x 1 bozbalci bozbalci 5382 Sep  8 00:28 hello_world

And it shows that hello_world is doing fine in ~/bin with its execution permissions set. I've tried rehash, but it didn't work. Help?

  • Do you have a tilde in the value of PATH, or in the command that sets PATH? You can write PATH=~/bin:/opt/texbin/… in a shell script, because the tilde is expanded. But if you run echo $PATH, it should show /home/theconjuring/bin:/opt/texbin:…. Where are you setting PATH? – Gilles 'SO- stop being evil' Sep 07 '14 at 21:46
  • Changing ~/bin to /home/bozbalci/bin solves the issue, thanks @Gilles! – Berk Özbalcı Sep 07 '14 at 21:52

2 Answers2

9

In a shell command like

PATH=~/bin:/opt/texbin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games

the tilde is expanded to your home directory when the shell command is executed. Thus the resulting value of PATH is something like /home/theconjuring/bin:/opt/texbin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games.

Make sure that the tilde isn't within quotes (PATH="~/bin:…"), otherwise it stands for itself. To prepend a directory to the current value of PATH, you can use

PATH=~/bin:$PATH

In general, in shells other than zsh, $PATH outside double quotes breaks when the value contains spaces or other special characters, but in an assignment, it's safe. With export, however, you need to write export PATH=~/bin:"$PATH" (though you don't need export with PATH since it's already in the environemnt). In zsh, you don't need double quotes except when the variable may be empty, but if you set PATH in .profile, it's processed by /bin/sh or /bin/bash.

If you're setting PATH in ~/.pam_environment, however, you can't use ~ or $HOME to stand for your home directory. This file is not parsed by a shell, it's a simple list of NAME=value lines. So you need to write the paths in full.

0

Update: bash will expand ~ in your PATH var. But beware, Python will not. I discovered this the hard way.

$ export PATH="~/foo:$PATH"
$ type -a foo.sh
foo.sh is /home/myles/foo/foo.sh
Python 3.9.11 (main, Sep  2 2022, 07:10:47)
Type 'copyright', 'credits' or 'license' for more information
IPython 8.6.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: shutil.which('foo.sh') None

  • The tilde really shouldn't get expanded in the shell if quoted (as the other answer says). Can you check what you get with e.g. bash -c 'FOO="~/foo"; echo "$FOO"' and are you sure you didn't actually do that without the quotes, possibly in an earlier command? – ilkkachu Jan 10 '23 at 18:48
  • The fact that Python (or whatever other scripting language) does not do its own tilde expansion is not really directly relevant to the current question, where the user is clearly working from the shell's command prompt. – Kusalananda Jan 10 '23 at 19:06
  • @ilkkachu As you can see, bash will expand a literla tilde when it searches your path Should it? Debatable I guess. But if bash (being the defacto reference) does it, then it would be nice if everyone else did too. $ bash -c 'FOO="~/foo"; echo "$FOO"' ~/foo $ mkdir ~/foo $ touch ~/foo/bar $ chmod +x ~/foo/bar $ bash -c 'PATH="~/foo"; echo $(which bar)' /home/epramyl/foo/bar $ bash -c 'PATH="~/foo"; echo $(which bar); echo $PATH' /home/mylesp/foo/bar ~/foo – Myles Prather Feb 17 '23 at 19:13
  • @MylesPrather, yep, looks like you're right, Bash does expand the tilde from PATH too. None of the other shells I tried do, though (zsh, Dash, ksh, Busybox). Based on the prompt in the original question, they're probably using zsh (or (t)csh), so what Bash does might not really help them. Leaving the tilde unquoted in the assignment to let it expand before the assignment to PATH would make it work with any shell. – ilkkachu Feb 17 '23 at 20:16