0

With ~/bin at the beginning of my $PATH, I still have to name the directory if I put 'nice time' in front of the filename. Also, 'which' doesn't find it yet it still runs if I invoke it without 'nice time bin/'. This was not the case at some time in the recent past. Is it a bug introduced recently, or a "feature" that Apple failed to support until recently?

MBP:~ user$ nice time copy_websites
copy_websites: No such file or directory
        0.00 real         0.00 user         0.00 sys
MBP:~ user$ echo $PATH
~/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Applications/Server.app/Contents/ServerRoot/usr/bin:/Applications/Server.app/Contents/ServerRoot/usr/sbin
MBP:~ user$ which copy_websites
MBP:~ user$ which bash
/bin/bash
MBP:~ user$ head -1 bin/copy_websites 
#!/bin/bash
MBP:~ user$ ls -lat@e bin/co*
-rwx------@ 1 user  staff  747 Mar 10 13:36 bin/copy_websites
    com.apple.TextEncoding   15 
    com.apple.metadata:kMDLabel_zla7g6mgqwkmgzlaez4j64ql5q   89 
  • What does type copy_websites say? Does it help if you replace the ~ in PATH with the expanded home folder? – nohillside Mar 11 '17 at 10:58
  • You have the tilde (~) quoted in your PATH variable assignment. You can use $HOME instead, inside the quoted assignment. – fd0 Mar 11 '17 at 12:07
  • ? I don't see any quote marks there. Is your meaning that ~ is not expanded in $PATH? Why did the behavior change? – WGroleau Mar 11 '17 at 12:29
  • Where and how exactly did you add ~/bin to the PATH? If, e.g., I add export PATH=~/bin:$PATH to my ~/.profile file, it properly expands it to /Users/me/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin. (I choose to use ~/.profile however you can use ~/.bash_profile or, ~/.bash_login.) What version of OS X/macOS are you running? – user3439894 Mar 11 '17 at 17:02
  • It is added in .bashrc which has not changed in months, probably more than a year. – WGroleau Mar 11 '17 at 18:18
0

The problem here is that the handling of ~ differs between the shell and the macOS kernel. If you run your command directly from the prompt, PATH expansion is handled by the shell which knows how to expand ~. If you run your command through nice, the command is passed to the macOS kernel for path expansion:

pse@Mithos:~$ mkdir foo
pse@Mithos:~$ cat >foo/foo.sh
#!/bin/sh
echo foo here
pse@Mithos:~$ chmod +x foo/foo.sh
pse@Mithos:~$ foo/foo.sh
foo here
pse@Mithos:~$ PATH='~/foo':$PATH
pse@Mithos:~$ echo $PATH
~/foo:/Users/pse/.bin/script:/Users/pse/.bin/i386:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/TeX/texbin
pse@Mithos:~$ foo.sh
foo here
pse@Mithos:~$ time foo.sh
foo here

real    0m0.007s
user    0m0.002s
sys 0m0.002s
pse@Mithos:~$ nice time foo.sh
foo.sh: No such file or directory
        0.00 real         0.00 user         0.00 sys
pse@Mithos:~$ nice foo.sh
nice: foo.sh: No such file or directory
pse@Mithos:~$ 

To avoid this, always make sure that your assigned PATH contains neither ~ nor any nonexpanded variables.

PS: Additionally there are different time commands called for time foo and nice time foo. To get the same output format in both cases, use /usr/bin/time foo instead.

  • So $HOME won't work as someone else said? – WGroleau Mar 11 '17 at 16:56
  • @WGroleau, If you use single or double quotes around ~, like matrix did PATH='~/foo':$PATH, it will not be expanded regardless of where or how you use it! In the default OS X/macOS shell, which is bash using an unquoted form of ~ will be expanded by the bash shell before being passed to the executable on the command line. If placed in e.g. ~/.profile, e.g.export PATH=~/bin:$PATH it's expanded as the bash shell opens. That said, I personally try to avoid using ~ and opt for either $HOME or /Users/me just to avoid any issue that might occur. – user3439894 Mar 11 '17 at 17:47
  • @patrix, Your command, PATH='~/foo':$PATH is not the correct way to add ~/anything to the PATH as it must be passed in an unquoted form to be expanded in a bash shell! – user3439894 Mar 11 '17 at 17:50
  • @user3439894 Yes, that's the whole point of my answer. The copy from Terminal is just to demonstrate the effect an unexpanded ~ has within PATH (same as the PATH shown in the question). – nohillside Mar 11 '17 at 18:44
  • 1
    @patrix, Okay, for a moment I wasn't sure, although from the overall quality of your answers, I should have been though, sorry. – user3439894 Mar 11 '17 at 18:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .