Search code examples
macosbashunixpathosx-elcapitan

Why is my PATH ignored?


Although my Unix PATH includes /Library/TeX/texbin this component of my PATH appears to be ignored. For example, when I try

pdftex --version

I get

-bash: pdftex: command not found

while

/Library/TeX/texbin/pdftex --version

works as expected.

Similarly,

where -a pdftex

gives no results.

My PATH is built from two sources: /private/etc/paths, which contains

/Users/Rax/.cabal/bin
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
/Users/Rax/bin

and two additional files in /private/etc/paths.d/40-XQuartz, and /private/etc/paths.d/TeX, which contain, respectively

/opt/X11/bin

and

/Library/TeX/texbin

Together these 3 files result in the expected PATH

$ echo $PATH
/Users/Rax/.cabal/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/Rax/bin:/opt/X11/bin:/Library/TeX/texbin

All the entries in the other directories are found as expected (inclusion those in /opt/X11/bin) but the last entry appears to be ignored (at least when locating executables).

Why is part of my PATH being ignored? How do I ensure that it is not, so that executables there are found as expected?


OS X 10.11.3


Solution

  • This got sorted out in the comments, but I'll post as an answer for the record: the problem was due to an invisible character in the PATH, that was being interpreted as part of the actual directory name. Specifically, it was a space at the end, but you could get the same effect from a number of other invisible characters. (I was actually guessing that one of the files in paths.d was in DOS/Windows text format, and had a carriage return at the end of the line.)

    To make invisible characters more visible, you can use printf or cat -vet:

    $ printf "%q\n" "$PATH"
    /Users/Rax/.cabal/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/Rax/bin:/opt/X11/bin:/Library/TeX/texbin\ 
    $ echo "$PATH" | LC_ALL=c cat -vet
    /Users/Rax/.cabal/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/Rax/bin:/opt/X11/bin:/Library/TeX/texbin $
    

    Note the \ at the end of the printf output -- it's actually followed by a space, but you have to infer that -- and the space before the $ in the cat -vet output. BTW, it's very important to put the reference to $PATH in double-quotes, since without them the space would've been trimmed.

    If it had been a carriage return instead, here's what it would have looked like:

    $ printf "%q\n" "$PATH"
    $'/Users/Rax/.cabal/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/Rax/bin:/opt/X11/bin:/Library/TeX/texbin\r'
    $ echo "$PATH" | LC_ALL=c cat -vet
    /Users/Rax/.cabal/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/Rax/bin:/opt/X11/bin:/Library/TeX/texbin^M$
    

    In this case, printf shows the carriage return as \r (and wraps the whole thing in $' ... ' to indicate that escapes should be interpreted), while cat -vet shows it as ^M.