Sysop: | Amessyroom |
---|---|
Location: | Fayetteville, NC |
Users: | 28 |
Nodes: | 6 (0 / 6) |
Uptime: | 47:31:41 |
Calls: | 422 |
Files: | 1,024 |
Messages: | 90,391 |
In article <vm9err$35gfs$1@dont-email.me>,
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
[snip]
Since you're referring to me, the OP, please note that most arguments
here have quickly made a relation to a straw man (a performance theme)
or made other deviations from the basic question(s) that concerned me.
Essentially there were two questions I had that I can reformulate in a
more compact form as
"Why, in the first place, are all these path components
part of the default PATH for ordinary users? - Is there
any [functional] rationale or necessity for that?"
Not particularly.
The system has, probably for no really principled reason,
evolved over time such that that's simply the set of things that
are in $PATH by default on that particular machine. Another
machine might be different.
If I had to hazard a guess, I imagine some of it comes from the
folks who put together the distribution, some upgrades, and the
choices of e.g. the window manager you're using (recalling that
at least one $PATH component appeared to come from that).
"_If_ many of the default PATH components are unnecessary,
where and how to best reduce these settings to a sensible
subset? - Without spoiling the system, of course."
There are many ways you could do this. Probably the easiest is
just to explicitly set $PATH in your shell's startup files to
those directories you care about; that's what I usually do. If
you make a mistake with it, you won't affect the rest of the
system.
If you want to set it globally for all users, there's likely
some file in /etc or similar that sets the defaults; on my Linux
machine I see a number of things in /etc/profile and
/etc/profile.d/* that seem relevant and there's /etc/login.defs;
PAM has its own way to set up $PATH. I'm not sure I'd bother,
though, if setting it up for your own account is sufficient.
... It seems to me that, as a normal user, the PATH
(and with it the path-search) could be drastically reduced. Is there
a method to only have them in the PATH when 'sudo'ing any programs
that require root privileges and the privileged programs in 'sbin'?
Yes, `sudo` can be configured to set $PATH for the programs that
it invokes; see sudoers(5) and look for `secure_path`. If you
don't invoke those from your normal shell, I don't see a problem
removing them from the default.
On 1/14/2025 8:55 AM, Dan Cross wrote:
... It seems to me that, as a normal user, the PATH
(and with it the path-search) could be drastically reduced. Is there
a method to only have them in the PATH when 'sudo'ing any programs
that require root privileges and the privileged programs in 'sbin'?
Yes, `sudo` can be configured to set $PATH for the programs that
it invokes; see sudoers(5) and look for `secure_path`. If you
don't invoke those from your normal shell, I don't see a problem
removing them from the default.
As for non-sudo PATH, you can always run:
export PATH=$(getconf PATH)
To get a minimal PATH setting guaranteed to include all POSIX
utilities.
[...]
I don't usually use bash, but if you do and you really don't
like this behavior you can turn it off.
[...]
Please don't put words in my mouth. [...]
[...]
As far as I can tell (I haven't investigated), all Bourne-based
shells other than Bash treat $PATH in the same way when executing
commands. Bash is the only shell I'm aware of that expands literal
'~' in $PATH.
The fact that it's not POSIX compliant behavior is at worst mildly
annoying. Bash correctly disables it in POSIX mode (enabled by the
--posix option, by running "set -o posix", by setting $POSIXLY_CORRECT
before starting bash, or by invoking it sas "sh").
I dislike the behavior because (a) it can quietly cause unexpected
problems (it's easy to miss the fact that $HOME is expanded within
double quotes and ~ is not), and (b) it's not documented. I certainly consider it a misfeature. [...]
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 24.01.2025 23:00, Keith Thompson wrote:
[...]
I mean that a shell should behave consistently. (I think Bash does
not in the given case.)
Consistently with what? Bash consistently expands literal '~'s in
$PATH, and consistently disables that expansion in POSIX mode.
[...]
It's a feature that (if used) leaks tildes into child processes via
the environment variable. Path resultion in child processes, if it
reaches a PATH element with a tilde, will somehow process that tilde.
I just tried this experiment. I made a directory named ~ and put ~:
as the leading element of PATH. I put a program called "foo" that
directory.
Surely enough, I can run "foo" from the parent directory above.
The exec functions treat ~ as an ordinary path component.
(I cannot do that out of Bash, which processes the tilde, but
the 'p' family of the exec functions will find it!)
This is a problem similar to "." being in PATH.
If someone has, say, "~/bin" in their PATH, ahead of /bin and /usr/bin,
I can put a malicious program in some directory called "~/bin"
somewhere in the filesystem, give that program the name of a common
external utility, and trick the user into changing into that location
where they will run this common command, resolving to my malicious
program.
If we regard this as a security hole, that atually raises the priority
and bolsters the argument that it ought to be removed even if it
breaks some users, perhaps through a process of noisy deprecation.
Furhermore, the case can be made that the exec stuff in the Linux kernel
or C libraries should be patched with a check against components with a leading tilde.
To my best knowledge using '/' as part of a file or directory name is
(as the '\0') prohibited by the operating system at a very low level.
So there would, IMO, not be a security hole (i.e. not because of that).
On 16.01.2025 00:26, Dan Cross wrote:
[snip]
I'm not sure I'd bother,
though, if setting it up for your own account is sufficient.
Yeah, you're probably right that this is the simplest thing to do.
On 20.01.2025 09:05, Wayne wrote:
As for non-sudo PATH, you can always run:
export PATH=$(getconf PATH)
To get a minimal PATH setting guaranteed to include all POSIX
utilities.
Yes, this comes very close to what I was actually aiming at. In
my environment that's just /bin and /usr/bin and this is what I
typically need in my scripts (plus sometimes /usr/local/bin).
But all the sbin directories (and other clutter) would be gone. It practically shows that these directories are unnecessary for a normal (non-root) user.
[...]
I am a late-comer to an interesting thread ...
I think that, depending on your Linux distribution, /bin and /sbin are symbolic links to their respective /usr counterparts [...]
So a tidy minimalist might opt for /bin only
(plus, if needed,
$HOME/bin, which is better than ~/bin, because tilde expansion is not,
AFAIK, included in POSIX) as non-root and /bin:/sbin else.
But all the sbin directories (and other clutter) would be gone. It
practically shows that these directories are unnecessary for a normal
(non-root) user.
Well, /usr/games is populated here ... (-:
Best regards
Axel
[Meta note: This is more of a comp.unix.shell sort of post; not
so much comp.unix.programmer. Followup-To: set accordingly.]
In article <vm5dei$2c7to$1@dont-email.me>,
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
When I recently inspected an 'strace' log and saw the huge amount
of system-calls done for a simple standard command (like 'rm') -
it's more than a dozen! and most lead just to ENOENT - I wondered
about the default PATH definition which is for my system
/usr/lib/lightdm/lightdm
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
(here I'm omitting my own additions, '~/bin' and '.', and I separated
them, one on each line for a better visualization of the "problem" or, >>maybe better, for the "questions".)
On a single-user system, it's not a huge deal, but on a
multiuser system where you may `cd` into a directory writable by
anyone (such as /tmp), `.` in $PATH is a known security problem.
YMMV, but caveat emptor.
The above PATH components are for a terminal running under some
window manager, a plain console window will not show the 'lightdm'
entry (but I rarely work on plain consoles).
This raises a few questions, and someone may shed some light on the >>rationale for above default settings... (and how to "fix" it best)
Why do I need 'lightdm/lightdm' in the user's PATH variable defined?
(That directory contains just one special script and one executable.)
This entry is what annoys me most; it also reminds me of systems that
have every program vendor add an own PATH entry for their products.
Would it be safe to just remove that (in my '~/.profile') from PATH?
Or can I make it vanish by some other change, to not appear in the
in the PATH first place? (Of course without destabilizing the system
by that.)
If you don't feel like you need to run that executable, and the
window manager works ok without it, I don't see why it would be
a problem to remove it from $PATH.
There's no files in '/usr/local/sbin' (on my system); no admins with >>special tools desires.
I don't seem to use executables from all the 'sbin' directories; I'm >>positive I need /usr/bin, /bin, and I've also installed some things
in /usr/local/bin. It seems to me that, as a normal user, the PATH
(and with it the path-search) could be drastically reduced. Is there
a method to only have them in the PATH when 'sudo'ing any programs
that require root privileges and the privileged programs in 'sbin'?
Yes, `sudo` can be configured to set $PATH for the programs that
it invokes; see sudoers(5) and look for `secure_path`. If you
don't invoke those from your normal shell, I don't see a problem
removing them from the default.
I mean, if I 'sodo' a shell I get - and I think this is sensible! -
only /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
(no 'lightdm', no 'games', and no personal settings) anyway, and I
seem to have those entries available independent of any parent
process's setting; PATH=/usr/bin sudo ksh will still provide all
the 'sbin' directories in the privileged shell's own PATH setting.
So my thought is, for the moment as a workaround, to edit the PATH
in the .profile, and _remove_ all 'sbin' and the 'lightdm' entries,
or just explicitly _define_ PATH without the spurious parts). (Or
would it be advisable to do that change in all the shells' .rc
files?) Or is there yet a better place to "fix" things system-wide?
(Or better not touch a running system? - but it looks so messy!)
Personally, I'd let well enough alone, but I suppose this
alludes to a larger question: does having those entries in $PATH
affect the operation of the system in any materially negative
way? Is this just a preference for tidiness kind of thing?
There's no harm in cleaning up, but I suspect any marginal
resource savings has already been offset by thinking about it
at all. :-)
What is the desired end-state here?
- Dan C.
[Meta note: This is more of a comp.unix.shell sort of post; not
so much comp.unix.programmer. Followup-To: set accordingly.]
In article <vm5dei$2c7to$1@dont-email.me>,
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
When I recently inspected an 'strace' log and saw the huge amount
of system-calls done for a simple standard command (like 'rm') -
it's more than a dozen! and most lead just to ENOENT - I wondered
about the default PATH definition which is for my system
/usr/lib/lightdm/lightdm
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
(here I'm omitting my own additions, '~/bin' and '.', and I separated
them, one on each line for a better visualization of the "problem" or,
maybe better, for the "questions".)
On a single-user system, it's not a huge deal, but on a
multiuser system where you may `cd` into a directory writable by
anyone (such as /tmp), `.` in $PATH is a known security problem.
YMMV, but caveat emptor.
The above PATH components are for a terminal running under some
window manager, a plain console window will not show the 'lightdm'
entry (but I rarely work on plain consoles).
This raises a few questions, and someone may shed some light on the
rationale for above default settings... (and how to "fix" it best)
Why do I need 'lightdm/lightdm' in the user's PATH variable defined?
(That directory contains just one special script and one executable.)
This entry is what annoys me most; it also reminds me of systems that
have every program vendor add an own PATH entry for their products.
Would it be safe to just remove that (in my '~/.profile') from PATH?
Or can I make it vanish by some other change, to not appear in the
in the PATH first place? (Of course without destabilizing the system
by that.)
If you don't feel like you need to run that executable, and the
window manager works ok without it, I don't see why it would be
a problem to remove it from $PATH.
There's no files in '/usr/local/sbin' (on my system); no admins with
special tools desires.
I don't seem to use executables from all the 'sbin' directories; I'm
positive I need /usr/bin, /bin, and I've also installed some things
in /usr/local/bin. It seems to me that, as a normal user, the PATH
(and with it the path-search) could be drastically reduced. Is there
a method to only have them in the PATH when 'sudo'ing any programs
that require root privileges and the privileged programs in 'sbin'?
Yes, `sudo` can be configured to set $PATH for the programs that
it invokes; see sudoers(5) and look for `secure_path`. If you
don't invoke those from your normal shell, I don't see a problem
removing them from the default.
I mean, if I 'sodo' a shell I get - and I think this is sensible! -
only /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
(no 'lightdm', no 'games', and no personal settings) anyway, and I
seem to have those entries available independent of any parent
process's setting; PATH=/usr/bin sudo ksh will still provide all
the 'sbin' directories in the privileged shell's own PATH setting.
So my thought is, for the moment as a workaround, to edit the PATH
in the .profile, and _remove_ all 'sbin' and the 'lightdm' entries,
or just explicitly _define_ PATH without the spurious parts). (Or
would it be advisable to do that change in all the shells' .rc
files?) Or is there yet a better place to "fix" things system-wide?
(Or better not touch a running system? - but it looks so messy!)
Personally, I'd let well enough alone, but I suppose this
alludes to a larger question: does having those entries in $PATH
affect the operation of the system in any materially negative
way? Is this just a preference for tidiness kind of thing?
There's no harm in cleaning up, but I suspect any marginal
resource savings has already been offset by thinking about it
at all. :-)
What is the desired end-state here?
- Dan C.
tilde expansion is not, AFAIK, included in POSIX
Axel Reichert wrote:
tilde expansion is not, AFAIK, included in POSIX
Incorrect. See XCU 2.6.1 Tilde Expansion, which includes the following:
In an assignment (see XBD Section 4.26), multiple tilde-prefixes
can be used: one at the beginning of the word (that is, following
the <equals-sign> of the assignment), or one following any unquoted
<colon>, or both.
The reason this is there is for things like PATH=~/bin:~/sbin:/bin:...
On 2025-01-22, Geoff Clare <geoff@clare.See-My-Signature.invalid> wrote:
Axel Reichert wrote:
tilde expansion is not, AFAIK, included in POSIX
Incorrect. See XCU 2.6.1 Tilde Expansion, which includes the following:
In an assignment (see XBD Section 4.26), multiple tilde-prefixes
can be used: one at the beginning of the word (that is, following
the <equals-sign> of the assignment), or one following any unquoted
<colon>, or both.
The reason this is there is for things like PATH=~/bin:~/sbin:/bin:...
But surely that must be expanded before PATH is assigned.
PATH is processed by the "p" exec functions like execlp. I don't
think these perform tilde expansion!
So the reason for using tilde in PATH assignments is the same reason
as using them in any other shell programming situation; to save
keystrokes over typing $HOME.
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.
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.
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.
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;
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.
- Dan C.
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.
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.
Bash behaves strange here; 'which' doesn't find the executable but nonetheless bash executes it, shows its output?
Bash behaves strange here; 'which' doesn't find the executable but nonetheless bash executes it, shows its output?
[…]
To me it appears that not finding (by 'which') an executable but
executing it nonetheless qualifies as a bug [in Bash].
Here's my bug report:
https://lists.gnu.org/archive/html/bug-bash/2025-01/msg00114.html
it cannot reasonably be anything other than replacement by $HOME,
which is the actual behavior that can be inferred from experiments.
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
[...]
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:
[snip]
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. [...]
"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, [...]
Another thing to remember is that variable references are expanded
within double quotes, but ~ is not:
$ echo "$HOME ~"
/home/kst ~
Going off on a tangent, there's a recent trend to make /bin a symlink to /usr/bin -- but the default $PATH on most systems still includes both /usr/bin and /bin. I wonder why that wasn't cleaned up.
Kaz Kylheku <643-408-1753@kylheku.com> writes:
[...]
The obvious situation is double quotes. Inside double quotes, parameter[...]
expansion happens, but not tilde expansion (not to mention pathname
expansion (globbing) and perhaps some other things).
So this won't work:
PATH="$PATH:~/bin"
Sorry I don't have details, but it is true nonetheless.
There they are.
In fact it probably will *partially* work. As I mentioned elsethread,
bash expands a leading ~ (or even ~username) in an element of $PATH when executing a command.
But if you run a program from the command line that invokes another
program (say, a C program that calls system()), it won't treat that
element of $PATH the same way.
For this and other reasons, though you *can* have a literal ~ in $PATH
in bash, it's best to avoid it and use $HOME instead.
A literal '$HOME'
won't work at all, but that's less likely to be a problem if your at all aware of how double quotes work in the shell.
I suggest that bash's undocumented behavior is less than helpful.
I'll probably submit a bug report.
Which which is which? Burn the which!
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.
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.
On 23.01.2025 17:47, Dan Cross wrote:
[snip]
: 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:
[snip]
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].
On 23.01.2025 23:46, Keith Thompson wrote:
[snip]
For this and other reasons, though you *can* have a literal ~ in $PATH
in bash, it's best to avoid it and use $HOME instead.
Or use it correctly, unquoted and unescaped.
As others have already pointed out, it's probably because you quoted the >tilde.
In article <vmvp3d$2671i$1@dont-email.me>,
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
On 23.01.2025 23:46, Keith Thompson wrote:
[snip]
For this and other reasons, though you *can* have a literal ~ in $PATH
in bash, it's best to avoid it and use $HOME instead.
Or use it correctly, unquoted and unescaped.
Or just don't use it, and then you don't have to worry about it.
In article <vmu94j$1q2lp$1@dont-email.me>,
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
Bash behaves strange here; 'which' doesn't find the executable but
nonetheless bash executes it, shows its output?
Bash doesn't behave strangely here at all. Outside of its POSIX
mode, it's free to implement whatever behavior it likes with
respect to `~` expansion, and this is the behavior the author
has chosen.
But, critically, that does not mean that the programs _that it
invokes_ have to do the same. So while `bash` can perform `~`
expansion on the components of $PATH when it's searching for a
program to execute, one shouldn't be surprised if other programs
don't do the same thing.
As was pointed out, `which` is not built into the shell, and
therefore, not obligated to follow `bash`'s expansion rules.
I've changed the above test frame to remove some unnecessary parts
to eliminate distracting complexity. The output for three shells:
Sorry, I think this cuts too much: the point was to show how the
different shells handle `~` in different contexts; the actual
strings that are in `$PATH` are important to show.
[...]
On 2025-01-23, Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
Bash behaves strange here; 'which' doesn't find the executable but
nonetheless bash executes it, shows its output?
which is a nonstandard command; the POSIX command is type.
In those systems where "which" exists at all, it is often
a locally brewed program that is not exactly the same like
the one in other systems.
In Debian and derivatives thereof, /usr/bin/which is a shell script.
I see that in MacOS, there is a /usr/bin/which whose --help
says to send mail to which-bugs<at>gnu.org; the man page
implicates a Carlo Wood as the culprit behind it.
It doesn't appear to be part of GNU Coreutils.
Which which is which? Burn the which!
On 24.01.2025 14:33, Dan Cross wrote:
In article <vmvp3d$2671i$1@dont-email.me>,
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
On 23.01.2025 23:46, Keith Thompson wrote:
[snip]
For this and other reasons, though you *can* have a literal ~ in $PATH >>>> in bash, it's best to avoid it and use $HOME instead.
Or use it correctly, unquoted and unescaped.
Or just don't use it, and then you don't have to worry about it.
But as a Ksh (or any non-Bash shell) user I don't have
to worry about it. (Why shall I see any issue with it?)
[snip]
But more importantly; shell programmers shall be well aware
of what quotes mean in shells! They are not just fancy things
or accessories that one may or may not use as one likes. They
have clear semantics and are essential in shell programming.
If you want tilde-expressions expanded _don't quote them_.
It's not much different from file-globbing; don't escape or
quote a '*' (or other globbing meta-characters) if you want
it to become expanded.
The suggestion to "not use" this ~ or that * is misguiding.
Know the shell concepts! - Or know your shell, at least,
with all its inconsistencies and/or (where applicable) bugs.
On 24.01.2025 14:46, Dan Cross wrote:
In article <vmu94j$1q2lp$1@dont-email.me>,
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
Bash behaves strange here; 'which' doesn't find the executable but
nonetheless bash executes it, shows its output?
Bash doesn't behave strangely here at all. Outside of its POSIX
mode, it's free to implement whatever behavior it likes with
respect to `~` expansion, and this is the behavior the author
has chosen.
But, critically, that does not mean that the programs _that it
invokes_ have to do the same. So while `bash` can perform `~`
expansion on the components of $PATH when it's searching for a
program to execute, one shouldn't be surprised if other programs
don't do the same thing.
As I see it, Bash does the same correct assignment to PATH in
case the tilde-expression is quoted or unquoted; here there's
no difference.
Quoted or escaped it's a literal tilde in PATH,
unquoted it's an expanded tilde-expression. (As in all those
shells; bash, ksh, zsh, dash, sh.)
As was pointed out, `which` is not built into the shell, and
therefore, not obligated to follow `bash`'s expansion rules.
And this (at least) seems to be the source of an inconsistency;
'which' is also in other shells not a built-in. But all other
shells I tested (ksh, zsh, dash, sh) handle it consistently;
if 'which' ("/usr/bin/which") detects no program [in PATH] it
should not execute some program. Other shells do that correctly.
I've changed the above test frame to remove some unnecessary parts
to eliminate distracting complexity. The output for three shells:
Sorry, I think this cuts too much: the point was to show how the
different shells handle `~` in different contexts; the actual
strings that are in `$PATH` are important to show.
The actual strings and their handling WRT PATH is actually the
same in all these shells!
Those test-cases have hidden the real problem,
The settings PATH=~/bin and PATH="~/bin" respectively shall
result in the same behavior across shells when searching for
programs; in the first case looking into "/home/someuser/bin/"
and in the second case looking into "./~/bin/" (i.e. a path
component with a local directory named "~").
It appears as if Bash invokes a tilde-expansion twice(!); once
[if unquoted] when the assignment happens, and another time
when the path-search is actually done.
Both of our test-cases
indicated that Bash seems to tilde-expand a PATH variable value
a second time;
so while 'which' (as other shells and programs)
will not find any executable in "./~/bin/" (which would be the
correct interpretation of a quoted "~/bin") Bash does.
That inconsistency - and deviating from all the other shells -,
if not a bug, looks like a Bad Design Idea if it's been done
deliberately. - YMMV.
In article <vn0bpf$29qe6$1@dont-email.me>,
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
On 24.01.2025 14:46, Dan Cross wrote:
In article <vmu94j$1q2lp$1@dont-email.me>,
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
Bash behaves strange here; 'which' doesn't find the executable but
nonetheless bash executes it, shows its output?
Bash doesn't behave strangely here at all. Outside of its POSIX
mode, it's free to implement whatever behavior it likes with
respect to `~` expansion, and this is the behavior the author
has chosen.
But, critically, that does not mean that the programs _that it
invokes_ have to do the same. So while `bash` can perform `~`
expansion on the components of $PATH when it's searching for a
program to execute, one shouldn't be surprised if other programs
don't do the same thing.
As I see it, Bash does the same correct assignment to PATH in
case the tilde-expression is quoted or unquoted; here there's
no difference.
Bash demonstrably does not assign the same thing to $PATH when
the `~` is quoted or escaped versus unquoted/unescaped: [...]
As was pointed out, `which` is not built into the shell, and
therefore, not obligated to follow `bash`'s expansion rules.
And this (at least) seems to be the source of an inconsistency;
'which' is also in other shells not a built-in. But all other
shells I tested (ksh, zsh, dash, sh) handle it consistently;
If it's not built into those shells, then those shells don't
"handle" `which` in any meaningful way, other than exec'ing it
as they would any other program.
But `which` was just an example of a program that's not built
into the shell that inspects $PATH, which it inherited from the
shell that invoked it.
The interesting point of the example was to show that, [...]
if 'which' ("/usr/bin/which") detects no program [in PATH] it
should not execute some program. Other shells do that correctly.
Why do you say this? As I wrote earlier, nothing prevents
`bash` from treating $PATH however it likes outside of its POSIX
mode, and its behavior is entirely correct according to the
rules by which it does things. If other shells do things
differently, then that's their behavior; bash need not be bound
by it.
[...]
The actual strings and their handling WRT PATH is actually the
same in all these shells!
No it's not; that was the point.
Those test-cases have hidden the real problem,
That's the thing; there is no "problem." There are some
differences between how shells behave, but they're different
programs, so why is that bad?
The settings PATH=~/bin and PATH="~/bin" respectively shall
result in the same behavior across shells when searching for
programs; in the first case looking into "/home/someuser/bin/"
and in the second case looking into "./~/bin/" (i.e. a path
component with a local directory named "~").
I don't see any reason why that _must_ be true.
Any given shell is free to interpret $PATH any way it choses, [...]
It appears as if Bash invokes a tilde-expansion twice(!); once
[if unquoted] when the assignment happens, and another time
when the path-search is actually done.
Yes. That's precisely what I was showing.
Both of our test-cases
indicated that Bash seems to tilde-expand a PATH variable value
a second time;
I fail to see where this is being done a "second time": it seems
more likly that `bash` doesn't make any special note of the `~`
in `PATH="~/bin:whatever"` until it actuall goes to run a
program.
so while 'which' (as other shells and programs)
will not find any executable in "./~/bin/" (which would be the
correct interpretation of a quoted "~/bin") Bash does.
You seem to have invented a definition of "correct" here and are
pursuing it aggressively, but that is just one definition from
a large set of such definitions; there's no reason to assume the
behavior you expect here is any more correct than what `bash`
does.
That inconsistency - and deviating from all the other shells -,
Careful: "all other shells" is a pretty big net, and it wouldn't
surprise me at all if this broke down if you expanded the set of
things you were looking at. If you really want to twist your
nogging, have a look at what `csh` does, for example.
if not a bug, looks like a Bad Design Idea if it's been done
deliberately. - YMMV.
It's obviously being done deliberately, and is easy to find in
the source code: https://git.savannah.gnu.org/cgit/bash.git/tree/findcmd.c#n533
You may consider it bad design, and you're well within your
rights to do so, but opinions on that vary, and it doesn't mean
yours is correct.
- Dan C.
~ is equivalent to $HOME in most contexts. I suggest that assuming that
~, like $HOME, is expanded in double quotes is a very easy mistake to
make. And the bash misfeature we're discussing can make it hard to
detect that mistake.
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 24.01.2025 14:46, Dan Cross wrote:[...]
/usr/bin/which is limited in what it can do. It follows POSIX-specified behavior for $PATH; it doesn't recognize any shell-specific rules. [...]
[...]
The settings PATH=~/bin and PATH="~/bin" respectively shall
result in the same behavior across shells when searching for
programs; in the first case looking into "/home/someuser/bin/"
and in the second case looking into "./~/bin/" (i.e. a path
component with a local directory named "~").
What do you mean by "shall result?
All shells that conform to POSIX behave as you describe. bash doesn't conform to POSIX unless you ask it to. Neither do csh, tcsh, and fish.
[...]
BTW, it hadn't occurred to me that you can have a relative path in a component of $PATH, but it does seem to work. I won't be taking
advantage of this information.
In article <vn0cno$29vrs$1@dont-email.me>,
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
On 24.01.2025 14:33, Dan Cross wrote:
In article <vmvp3d$2671i$1@dont-email.me>,
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
On 23.01.2025 23:46, Keith Thompson wrote:
[snip]
For this and other reasons, though you *can* have a literal ~ in $PATH >>>>> in bash, it's best to avoid it and use $HOME instead.
Or use it correctly, unquoted and unescaped.
Or just don't use it, and then you don't have to worry about it.
But as a Ksh (or any non-Bash shell) user I don't have
to worry about it. (Why shall I see any issue with it?)
Because you might want to put whatever you assign to `PATH`
in quotes, for instance if their are spaces in one of the
component pathnames (people run `bash` on windows and all
kinds of weird places) and the behavior differs. $HOME is
pleasantly boring by comparison.
[snip]
But more importantly; shell programmers shall be well aware
of what quotes mean in shells! They are not just fancy things
or accessories that one may or may not use as one likes. They
have clear semantics and are essential in shell programming.
If you want tilde-expressions expanded _don't quote them_.
What if the expression refers to a file name with a space in
it? Of course, one can escape the whitespace characters in
filenames, but that gets tedious.
[snip]
You may consider it bad design, and you're well within your
rights to do so, but opinions on that vary, and it doesn't mean
yours is correct.
So you think that behavior of Bash is good design here? - Okay,
noted.
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 24.01.2025 23:00, Keith Thompson wrote:
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 24.01.2025 14:46, Dan Cross wrote:[...]
/usr/bin/which is limited in what it can do. It follows POSIX-specified >>> behavior for $PATH; it doesn't recognize any shell-specific rules. [...]
Sure.
[...]
The settings PATH=~/bin and PATH="~/bin" respectively shall
result in the same behavior across shells when searching for
programs; in the first case looking into "/home/someuser/bin/"
and in the second case looking into "./~/bin/" (i.e. a path
component with a local directory named "~").
What do you mean by "shall result?
I mean that a shell should behave consistently. (I think Bash does
not in the given case.)
Consistently with what? Bash consistently expands literal '~'s in
$PATH, and consistently disables that expansion in POSIX mode.
All shells have shell-specific features. What's odd about this case is
that bash has a POSIX-violating feature that affects command name
resolution.
you don't want to miss. - So Bash users, if they don't want to get
bitten in a subtle way, are probably advised to be pointed out to
that behavior, or, as suggested by others already, not to use tilde
at all with PATH in Bash.
To my best knowledge using '/' as part of a file or directory name is
(as the '\0') prohibited by the operating system at a very low level.
On Sun, 26 Jan 2025 14:49:16 +0100, Janis Papanagnou wrote:
To my best knowledge using '/' as part of a file or directory name is
(as the '\0') prohibited by the operating system at a very low level.
But you can use in a file/directory name.
Lawrence D'Oliveiro <ldo@nz.invalid> writes:
But you can use “∕” in a file/directory name.
Not in a POSIX-conforming way:
On Sun, 26 Jan 2025 14:49:16 +0100, Janis Papanagnou wrote:
To my best knowledge using '/' as part of a file or directory name is
(as the '\0') prohibited by the operating system at a very low level.
But you can use <line noise> in a file/directory name.
Not in a POSIX-conforming way:
In article <vn2hsj$2pe96$1@dont-email.me>,
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
[snip]
Most of this discussion seems to be talking at cross-purposes.
I don't see much point in responding to the specifics.
My point was simply to show that shell behavior varies with
respect to how $PATH is treated; caveat emptor.
I don't usually use bash, but if you do and you really don't
like this behavior you can turn it off.
As far as I can tell, you can only turn off the behavior by
running in POSIX mode, which disables a lot of other Bash-specific >functionality. Personally, I'm unwilling to do that. I think I'd
like to see a "set -o" setting that disables just this feature.
You can *avoid* it by being careful not to put literal '~' characters
in $PATH (specifically at the beginning of any element of $PATH).
That's what I do (unintentionally before now, deliberately now that
I know about it.)
On 2025-01-26, Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
you don't want to miss. - So Bash users, if they don't want to get
bitten in a subtle way, are probably advised to be pointed out to
that behavior, or, as suggested by others already, not to use tilde
at all with PATH in Bash.
That's a bizarre recommendation. Approximately all uses of tilde
in PATH are variants of PATH=~/bin:$PATH, which are expanded on
assignment in bash as in other sh-type shells.
On 2025-01-26, Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
To my best knowledge using '/' as part of a file or directory name is
(as the '\0') prohibited by the operating system at a very low level.
So there would, IMO, not be a security hole (i.e. not because of that).
The / is not part of a name; it is acting as the path component
separator. [...]
*directory* called "~/bin"
On Sun, 26 Jan 2025 14:49:16 +0100, Janis Papanagnou wrote:
To my best knowledge using '/' as part of a file or directory name is
(as the '\0') prohibited by the operating system at a very low level.
But you can use “∕” in a file/directory name.
On Sun, 26 Jan 2025 14:49:16 +0100, Janis Papanagnou wrote:
To my best knowledge using '/' as part of a file or directory name is
(as the '\0') prohibited by the operating system at a very low level.
But you can use “∕” in a file/directory name.
Lawrence D'Oliveiro <ldo@nz.invalid> writes:
On Mon, 27 Jan 2025 15:48:21 +1100, Alexis wrote:[...]
Lawrence D'Oliveiro <ldo@nz.invalid> writes:
But you can use “∕” in a file/directory name.
Not in a POSIX-conforming way:
ldo@theon:trydir> mkdir f1
ldo@theon:trydir> touch f1/f2
ldo@theon:trydir> touch f1∕f2
Yes, yes, we all know what you're saying, and we all hope you've
enjoyed the attention.
Of course the '/' character can appear in a pathname. And of course it cannot appear in a pathname component, which POSIX also calls a
"filename".
On 27.01.2025 01:02, Lawrence D'Oliveiro wrote:
On Sun, 26 Jan 2025 14:49:16 +0100, Janis Papanagnou wrote:
To my best knowledge using '/' as part of a file or directory name is
(as the '\0') prohibited by the operating system at a very low level.
But you can use “∕” in a file/directory name.
You can use it in file and directory _paths_ as separator.
On Sun, 26 Jan 2025 23:51:33 -0800, Keith Thompson wrote:
Of course the '/' character can appear in a pathname. And of course it
cannot appear in a pathname component, which POSIX also calls a
"filename".
But you can use in a file/directory name.
Another interesting tidbit: the GNU `which` command has a "--skip-tilde" option that tells it to skip elements of $PATH that start with '~'
(and also directories anywhere under $HOME).
From the output of `which --help`:
--skip-tilde Skip directories in PATH that start with a tilde.