Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
448 views
in Technique[技术] by (71.8m points)

linux - Should PATH contain directories or full paths to binaries?

I am trying to set up a correct PATH, but I'm wondering what it should contain. If I have

/usr/bin/ls
/usr/local/bin/ls

and I want to prefer the one in /usr/local/bin, which of the following should I use?

PATH=/usr/local/bin/ls:/usr/bin/ls
PATH=/usr/local/bin:/usr/bin

or something else entirely?

This is not per se a suitable question for Stack Overflow. I expect this to be closed as General Computing or Too Broad; but the answer is frequently needed by beginners, so I hope this won't be deleted.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

PATH works only with directories, not with single files

From the POSIX standard (emphasis mine)

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 ( ':' ). [...] 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.

When you type in ls into your shell and your PATH is set to /usr/local/bin/ls:/usr/bin/ls then your shell will …

  1. … look for an executable with the path /usr/local/bin/ls/ls (note the double ls at the end).

  2. As that path does not exist on your system your shell will proceed to look for an executable with the path /usr/bin/ls/ls (double ls again). That path also doesn't exist.

  3. The shell couldn't find an executable using all paths in PATH so your shell will print something like bash: ls: command not found.

So, what did we learn? Paths listed by PATH have to be directories. You cannot list single files. Therefore the correct answer in your case is PATH=/usr/local/bin:/usr/bin.


Where things get interesting

Imagine the following situation. You have two versions of program c1 and two versions of program c2. The different versions are stored in the directories /a/ and /b/.

/a/c1
/a/c2
/b/c1
/b/c2

How can we set PATH to prefer /a/c1 over /b/c1/ but at the same time /b/c2 over /a/c2?

Sadly, there is no way to achieve this directly as we can only specify directories in PATH. We have to move/rename some files or create symlinks and use the symlinks inside the paths. One possible solution:

mkdir /c
ln -s /a/c1 /c/c1
ln -s /b/c2 /c/c2
export PATH=/c:/a:/b

The trailing :/a:/b is not really necessary here. I included them under the assumption that /a and /b contain more executables than just c1 and c2.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...