[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Tilde is expanded in $PATH, inconsistent behavior
From: |
Keith Thompson |
Subject: |
Tilde is expanded in $PATH, inconsistent behavior |
Date: |
Thu, 23 Jan 2025 15:37:32 -0800 |
Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -g -O2 -Werror=implicit-function-declaration
-fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -flto=auto
-ffat-lto-objects -fstack-protector-strong -fstack-clash-protection
-Wformat -Werror=format-security -fcf-protection -Wall
uname output: Linux sal 6.11.0-13-generic #14-Ubuntu SMP
PREEMPT_DYNAMIC Sat Nov 30 23:51:51 UTC 2024 x86_64 x86_64 x86_64
GNU/Linux
Machine Type: x86_64-pc-linux-gnu
Bash Version: 5.2
Patch Level: 32
Release Status: release
Description:
A literal '~' or other tilde-prefix at the beginning of an
element of $PATH is expanded when a command is executed
from the bash prompt. This is undocumented and inconsistent with
the behavior of other commands that can execute commands.
This expansion doesn't happen when bash is invoked as "/bin/sh"
(which is a symlink to bash on some systems).
The "Tilde Expansion" section of the bash manual does talk about
using '~' when setting $PATH, but that applies only when setting
it, not when using a $PATH containing literal '~' characters.
A user who doesn't realize that, for example, "$HOME/bin" is
expanded in double quotes but "~/bin" is not might end up with
a $PATH setting that allows direct execution of some commands
from the bash prompt, but those same commands can't be found by
other tools.
I haven't run into this issue myself. This bug report is the
result of a recent discussion in comp.unix.shell.
Repeat-By:
Run this script:
```
#!/bin/bash
verbosely() {
echo "\$ $*"
"$@" || echo exit $?
}
export PATH='~/bin:/usr/bin:/bin'
echo "PATH=$PATH"
echo "HOME=$HOME"
verbosely type fnord
verbosely fnord # This works (and arguably shouldn't)
cat >run-fnord.c <<EOF
#include <stdlib.h>
int main(void) { system("fnord"); }
EOF
verbosely cat run-fnord.c
verbosely gcc run-fnord.c -o run-fnord
verbosely ./run-fnord # This doesn't work
```
The output on my system is:
```
PATH=~/bin:/usr/bin:/bin
HOME=/home/kst
$ type fnord
fnord is /home/kst/bin/fnord
$ fnord
This is fnord
$ cat run-fnord.c
#include <stdlib.h>
int main(void) { system("fnord"); }
$ gcc run-fnord.c -o run-fnord
$ ./run-fnord
sh: 1: fnord: not found
```
Fix:
I haven't looked at the source code that implements this.
I suggest documenting this feature in the next release and marking
it as obsolescent, and then removing it in a later release.
There could be existing code that depends on it -- which I
suppose argues against removing it at all. The documentation
should at least mention that the expansion occurs and discuss
this inconsistent treatment of $PATH by bash vs. other tools.
- Tilde is expanded in $PATH, inconsistent behavior,
Keith Thompson <=