Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encourage $HOME over tilde (~) for dash/gnutls/make compatibility #195

Closed
mcandre opened this issue Jul 18, 2014 · 5 comments
Closed

Encourage $HOME over tilde (~) for dash/gnutls/make compatibility #195

mcandre opened this issue Jul 18, 2014 · 5 comments

Comments

@mcandre
Copy link
Contributor

mcandre commented Jul 18, 2014

I've been bitten a few times by trying to use tildes in my scripts, especially when setting my PATH variable. When GNU make tries to find executables, it fails to find them, because it likes to fork out shells with dash instead of bash, and dash does not translate tildes. I love linting my scripts and dotfiles with shellcheck, but shellcheck doesn't catch this for me yet.

Could we please add a linting rule encouraging $HOME over ~ for dash/gnutls/make compatibility?

@ormaaj
Copy link

ormaaj commented Jul 21, 2014

Tilde expansion is required by POSIX and consequently supported by dash and all other compatible shells. Tilde expansion has additional capabilities that HOME does not such as ~+, ~-, and ~USER, which are also specified by POSIX, so even if you do prefer HOME in limited cases it can't be considered a rule.

Make is not shell. There should never be a case where shell code is evaluated by make. The only time a shell script should be together with make is if make is invoking a shell. You should never have a literal ~ in PATH and expect anything to expand it. A literal $HOME won't work either.

@mcandre
Copy link
Contributor Author

mcandre commented Jul 21, 2014

You should never have a literal ~ in PATH and expect anything to expand it. A literal $HOME won't work either.

On my computers, a literal ~ is expanded in $PATH in bash, but not in make.

On my computers, $HOME is expanded in both bash and make. According to the #bash community, this behavior is correct for make (and for the program it uses to shell out, dash), and shell script authors are advised to use $HOME over ~, though of course absolute paths are good, too.

  • bash 4.0
  • make 3.81
  • Ubuntu 14.04
  • Mac OS X 10.9.4 Mavericks

@ormaaj
Copy link

ormaaj commented Jul 21, 2014

It sounds to me like you've discovered a bug in Bash. No other shell does it and it isn't documented in the bash manual or specified by POSIX or any other documentation I've read. What you describe only appears to apply to ~, not HOME.

test:

#!/bin/bash
printf '%s\n' '#!/bin/sh' 'echo test' >~/tmpdir/testscript
chmod u+x ~/tmpdir/testscript
s=(bash ksh mksh posh zsh dash bb jsh)

for sh in "${s[@]}"; do
    printf '%-4s %s\n' "${sh}:" "$("$sh" -c 'PATH=\${HOME}/tmpdir; testscript' 2>&1)"
done
echo

for sh in "${s[@]}"; do
    printf '%-4s %s\n' "${sh}:" "$("$sh" -c 'PATH=\~/tmpdir; testscript' 2>&1)"
done

output:

bash: bash: testscript: command not found
ksh: ksh: testscript: not found
mksh: mksh: testscript: not found
posh: posh: testscript: not found
zsh: zsh:1: command not found: testscript
dash: dash: 1: testscript: not found
bb:  bb: testscript: not found
jsh: jsh: testscript: not found

bash: test
ksh: ksh: testscript: not found
mksh: mksh: testscript: not found
posh: posh: testscript: not found
zsh: zsh:1: command not found: testscript
dash: dash: 1: testscript: not found
bb:  bb: testscript: not found
jsh: jsh: testscript: not found

I don't think it's likely Bash is correct in expanding the tilde during command search. You should definitely not put either $HOME or ~ into PATH. There's no reason for it.

@mcandre
Copy link
Contributor Author

mcandre commented Jul 21, 2014

Oh, that's interesting!

Here's my .bashrc as another example:

https://github.com/mcandre/dotfiles/blob/master/.bashrc-wi

Thanks for taking an interest in this question. I don't know why things are
they way they are, I just want make to see my darn binaries!

On Mon, Jul 21, 2014 at 6:05 PM, Dan Douglas notifications@github.com
wrote:

It sounds to me like you've discovered a bug in Bash. No other shell does
it and it isn't documented in the bash manual or specified by POSIX or any
other documentation I've read. What you describe only appears to apply to
~, not HOME.
test:

#!/bin/bash
printf '%s\n' '#!/bin/sh' 'echo test' >~/tmpdir/testscript
chmod u+x ~/tmpdir/testscript
s=(bash ksh mksh posh zsh dash bb jsh)

for sh in "${s[@]}"; do
printf '%-4s %s\n' "${sh}:" "$("$sh" -c 'PATH=${HOME}/tmpdir; testscript' 2>&1)"
done
echo

for sh in "${s[@]}"; do
printf '%-4s %s\n' "${sh}:" "$("$sh" -c 'PATH=~/tmpdir; testscript' 2>&1)"
done

output:

bash: bash: testscript: command not found
ksh: ksh: testscript: not found
mksh: mksh: testscript: not found
posh: posh: testscript: not found
zsh: zsh:1: command not found: testscript
dash: dash: 1: testscript: not found
bb: bb: testscript: not found
jsh: jsh: testscript: not found

bash: test
ksh: ksh: testscript: not found
mksh: mksh: testscript: not found
posh: posh: testscript: not found
zsh: zsh:1: command not found: testscript
dash: dash: 1: testscript: not found
bb: bb: testscript: not found
jsh: jsh: testscript: not found

I don't think it's likely Bash is correct in expanding the tilde during
command search. You should definitely not put either $HOME or ~ into PATH.
There's no reason for it.


Reply to this email directly or view it on GitHub
#195 (comment).

Cheers,

Andrew Pennebaker
www.yellosoft.us

@koalaman
Copy link
Owner

Nice one. 0347ce1 warns about quoted ~s being assigned in PATH. It's not perfect, but should catch most instances.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants