| Deutsch English Français Italiano |
|
<878qr1nqs0.fsf@nosuchdomain.example.com> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail
From: Keith Thompson <Keith.S.Thompson+u@gmail.com>
Newsgroups: comp.unix.shell
Subject: Re: Default PATH setting - reduce to something more sensible?
Date: Thu, 23 Jan 2025 13:50:39 -0800
Organization: None to speak of
Lines: 186
Message-ID: <878qr1nqs0.fsf@nosuchdomain.example.com>
References: <vm5dei$2c7to$1@dont-email.me> <20250122120930.74@kylheku.com>
<ccr96l-eot.ln1@ID-313840.user.individual.net>
<vmthmu$3bb88$1@news.xmission.com> <vmtrqk$92b$1@reader2.panix.com>
<vmu94j$1q2lp$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Date: Thu, 23 Jan 2025 22:50:40 +0100 (CET)
Injection-Info: dont-email.me; posting-host="cfbd9e7c39946649fd7b1a396904b2c2";
logging-data="1916163"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/YUH0W09/SCAzr92L3CS76"
User-Agent: Gnus/5.13 (Gnus v5.13)
Cancel-Lock: sha1:K9CR9vhmz/57PdeJ3pMvYSDpMX0=
sha1:AmbStxy47FDSgSEphKBH0/7jb8c=
Bytes: 8425
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
> On 23.01.2025 17:47, Dan Cross wrote:
>> In article <vmthmu$3bb88$1@news.xmission.com>,
>> Kenny McCormack <gazelle@shell.xmission.com> wrote:
>>> In article <ccr96l-eot.ln1@ID-313840.user.individual.net>,
>>> Geoff Clare <netnews@gclare.org.uk> wrote:
>>> ...
>>>> Yes. Perhaps I trimmed too much. The post I was replying to said
>>>> "$HOME/bin [..] is better than ~/bin, because tilde expansion is not,
>>>> AFAIK, included in POSIX" and $HOME is also, of course, expanded before
>>>> PATH is assigned. So there is no reason to prefer $HOME/bin over ~/bin
>>>> since (when used in an assignment) they are equivalent in POSIX.
>>>
>>> 1) I have no idea what your beef with Kaz is. It seems silly at best.
>>
>> The response you're replying to seemed pretty collegial to me;
>> am I missing something?
>>
>>> 2) I know this isn't going to sit well with you, but there absolutely are
>>> situations (in bash) where ~ doesn't work as a substitute for $HOME, when
>>> setting the various "path" variables. I know that I had lines in .profile
>>> and/or .bashrc like: PATH=~/bin:$PATH (and similar) that did not work (that
>>> is, the value stored in the variable contained an explicit tilde rather
>>> than the expanded value - and this, of course, doesn't work at runtime).
>>> Replacing the tilde with $HOME fixes this.
>>>
>>> Sorry I don't have details, but it is true nonetheless.
>>
>> I think the issue is that one wants to prevent a literal string
>> like `~/bin` from showing up in $PATH. While a given shell
>> _may_ interpret such $PATH components as being relative to the
>> user's home directory (`bash` does) others may not (`ksh` does
>> not, at least not by default).
>>
>> Further, C library functions like `execlp`, `execvp` and
>> `execvpe` that refer to $PATH may not handle `~` expansion, and
>> are not mandated to where defined by e.g. POSIX. Similarly for
>> analogous functions in other programming languages. Given that
>> programs that make use of those functions inherit $PATH when
>> invoked from a shell, this can lead to unexpected behavior in a
>> way that's hard to diagnose ("it works fine when I run this
>> program from the shell, but my editor can't find it!").
>>
>> Also, it's not the case that shells always expand `~` when
>> setting $PATH, even when $HOME would be expanded, as Kenny
>> points out. Here's an example:
>>
>> : term; echo $HOME
>> /home/cross
>> : term; pwd
>> /home/cross
>> : term; echo echo xyzzy >bin/quux
>> : term; chmod +x bin/quux
>> : term; which quux
>> /home/cross/bin/quux
>> : term; quux
>> xyzzy
>> : term; exec ksh
>> : term; export PATH=~/bin:/bin:/usr/bin
>> : term; echo $PATH
>> /home/cross/bin:/bin:/usr/bin
>> : term; which quux
>> /home/cross/bin/quux
>> : term; quux
>> xyzzy
>> : term; export PATH="$HOME/bin:/bin:/usr/bin"
>> : term; echo $PATH
>> /home/cross/bin:/bin:/usr/bin
>> : term; which quux
>> /home/cross/bin/quux
>> : term; quux
>> xyzzy
>> : term; export PATH="~/bin:/bin:/usr/bin"
>> : term; echo $PATH
>> ~/bin:/bin:/usr/bin
>> : term; which quux
>> : term; quux
>> ksh: quux: not found
>> : term; exec /usr/pkg/bin/bash
>> : term; echo $PATH
>> ~/bin:/bin:/usr/bin
>> : term; which quux
>> : term; quux
>> xyzzy
>> : term;
>
> Bash behaves strange here; 'which' doesn't find the executable but
> nonetheless bash executes it, shows its output?
>
> I've changed the above test frame to remove some unnecessary parts
> to eliminate distracting complexity. The output for three shells:
>
> Bash:
> /home/jap/bin/quux
> xyzzy
> /home/jap/bin/quux
> xyzzy
> xyzzy
> # nothing returned from 'which' (silent), *no error* on call [***]
>
> Ksh:
> /home/jap/bin/quux
> xyzzy
> /home/jap/bin/quux
> xyzzy
> ksh: quux: not found
> # nothing returned from 'which' (silent), error on call
>
> Zsh:
> /home/jap/bin/quux
> xyzzy
> /home/jap/bin/quux
> xyzzy
> quux not found
> zsh:1: command not found: quux
> # diagnostic returned from 'which', error on call
>
> I'm not sure whether that effect is (as was suspected) an effect of
> a quoted '~'; it seems to be some different problem, in Bash.[***]
>
> For all these shells a quoted '~' as in the PATH assignation will be
> stored as a literal and will not get expanded; so far, so expected.
>
> A quoted '~' will not get expanded, so the result is not surprising.
> Tilde expansion comes before quote removal. (In Ksh, to be sure, and
> obviously also in the other shells, and I'd suppose also according
> to POSIX.)
>
>>
>> I suppose the moral is, for maximal portability, prefer using
>> $HOME (or another similar variable) to `~` when setting $PATH
>> unless you're doing so in a context where you are sure that `~`
>> will be expanded during assignment.
>
> IMO, the consequence is to not quote a tilde expression in the first
> place if you want it expanded in a shell variable. *Violating* that
> rule will _in Bash_ produce this strange effect (in the given setup).
>
> To me it appears that not finding (by 'which') an executable but
> executing it nonetheless qualifies as a bug [in Bash].
I wouldn't call it a bug in bash. Rather, it's a mismatch between bash
and which.
"which" is an external command, not a shell builtin. On my system, it's
a /bin/sh script in /usr/bin (to which /bin is a symlink). It searches
the directories in $PATH for a named executable. Apparently it doesn't
recognize '~' as a special character. (csh has a builtin "which"
command. tcsh has a builtin "which" and a builtin "where", which was my
tool of choice for this kind of thing back when I was a tcsh user.)
"type" is a bash builtin that mostly does what "which" does, but it also
has access to all of bash's internal information (functions, aliases,
keywords, builtin functions). "type" is specified by POSIX for sh, with
a description that implies it must be a shell builtin command. The bash
"type" command has several options as well.
I'm not sure why bash users use "which" rather than "type". I find
"type" far more useful.
The weirdness here is that, when executing a command, bash apparently
expands a leading '~' in an element of $PATH to $HOME. It even expands
a leading '~username'. As far as I can tell, this is not documented.
It does say:
"""
Bash checks each variable assignment for unquoted tilde-prefixes
immediately following a ':' or the first '=', and performs tilde
expansion in these cases. Consequently, one may use filenames with
tildes in assignments to 'PATH', 'MAILPATH', and 'CDPATH', and the shell
assigns the expanded value.
"""
but that applies when setting $PATH, not when using it.
Another thing to remember is that variable references are expanded
within double quotes, but ~ is not:
$ echo "$HOME ~"
/home/kst ~
========== REMAINDER OF ARTICLE TRUNCATED ==========