问题
Based on my testing, bash is very happy with ~ in $PATH but /usr/bin/which is not. Is there any standard (like POSIX) regarding this?
Example:
[STEP 100] # echo $BASH_VERSION
4.4.12(1)-release
[STEP 101] # echo $PATH
/root/bin:/usr/sbin:/usr/bin:/sbin:/bin
[STEP 102] # /usr/bin/which passh
/root/bin/passh
[STEP 103] # type passh
passh is /root/bin/passh
[STEP 104] #
[STEP 105] # PATH='~/bin':/usr/sbin:/usr/bin:/sbin:/bin
[STEP 106] # echo $PATH
~/bin:/usr/sbin:/usr/bin:/sbin:/bin
[STEP 107] # /usr/bin/which passh
[STEP 108] # hash -r
[STEP 109] # hash
hash: hash table empty
[STEP 110] # type passh
passh is /root/bin/passh
[STEP 111] #
As we can see, in step 107 which cannot find passh any more but in step 110 bash can still find passh after I clear the hash table (hash -r).
回答1:
You have this part in PATH variable: '~/bin'
Here ~ is quoted and doesn't get expanded. This can be handled by bash builtin utilities like type but which is an external program that doesn't expand quoted ~.
If you want ~ to expand then keep it outside the quotes as:
PATH=~/bin:/usr/local/bin:/usr/local/sbin:/usr/sbin:/usr/bin:/sbin:/bin
Or use $HOME:
PATH="$HOME/bin":/usr/local/bin:/usr/local/sbin:/usr/sbin:/usr/bin:/sbin:/bin
回答2:
Found following info in POSIX.1-2008:
XBD - 8.3 Other Environment Variables
PATH
This variable shall represent the sequence of path prefixes that certain functions and utilities apply in searching for an executable file known only by a filename. The prefixes shall be separated by a colon (:). When a non-zero-length prefix is applied to this filename, a slash shall be inserted between the prefix and the filename if the prefix did not end in slash. A zero-length prefix is a legacy feature that indicates the current working directory. It appears as two adjacent colon characters (::), as an initial colon preceding the rest of the list, or as a trailing colon following the rest of the list. A strictly conforming application shall use an actual pathname (such as.) to represent the current working directory inPATH. The list shall be searched from beginning to end, applying the filename to each prefix, until an executable file with the specified name and appropriate execution permissions is found. If the pathname being sought contains a slash, the search through the path prefixes shall not be performed. If the pathname begins with a slash, the specified path is resolved . IfPATHis unset or is set to null, the path search is implementation defined.Since colon is a separator in this context, directory names that might be used in
PATHshould not include a colon character.
And from Glibc 2.22 doc:
25.4.2 Standard Environment Variables
- PATH
A path is a sequence of directory names which is used for searching for a file. The variablePATHholds a path used for searching for programs to be run. Theexeclpandexecvpfunctions use this environment variable, as do many shells and other utilities which are implemented in terms of those functions. The syntax of a path is a sequence of directory names separated by colons. An empty string instead of a directory name stands for the current directory.
来源:https://stackoverflow.com/questions/44704710/tilde-char-in-path-e-g-path-bin-usr-bin-bin