PATH 是不是应该包含二进制文件的目录或完整路径?

Posted

技术标签:

【中文标题】PATH 是不是应该包含二进制文件的目录或完整路径?【英文标题】:Should PATH contain directories or full paths to binaries?PATH 是否应该包含二进制文件的目录或完整路径? 【发布时间】:2019-12-08 16:09:15 【问题描述】:

我正在尝试设置正确的PATH,但我想知道它应该包含什么。如果我有

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

我想更喜欢/usr/local/bin 中的那个,我应该使用以下哪个?

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

还是完全不同的东西?

本身不是一个适合 Stack Overflow 的问题。 我希望这将作为通用计算或太宽泛而关闭; 但是答案是初学者经常需要的,希望不要被删。

【问题讨论】:

您似乎在询问 $PATH 优先级已经有问题的答案:***.com/q/33966080/7939871 不,重复是关于优先级的,但这特别是关于PATH 中的每个组件应该是什么。这个问题已经展示了优先级逻辑如何工作的知识。 【参考方案1】:

PATH 仅适用于目录,不适用于单个文件

来自POSIX standard(强调我的)

路径 此变量应表示某些功能和实用程序在搜索仅由文件名知道的可执行文件时应用的路径前缀序列。前缀应以冒号 (':') 分隔。 [...] 应从头到尾搜索列表,将文件名应用于每个前缀,直到找到具有指定名称和适当执行权限的可执行文件。

当您在 shell 中输入 ls 并且您的 PATH 设置为 /usr/local/bin/ls:/usr/bin/ls 时,您的 shell 将……

    ... 查找路径为 /usr/local/bin/ls/ls 的可执行文件(注意末尾的双 ls)。

    由于您的系统上不存在该路径,您的 shell 将继续查找路径为 /usr/bin/ls/ls 的可执行文件(再次为双 ls)。这条路也不存在。

    shell 无法使用 PATH 中的所有路径找到可执行文件,因此您的 shell 将打印类似 bash: ls: command not found 的内容。

那么,我们学到了什么? PATH列出的路径是目录。您不能列出单个文件。因此,您的正确答案是PATH=/usr/local/bin:/usr/bin


有趣的地方

想象以下情况。您有两个版本的程序 c1 和两个版本的程序 c2。不同的版本存储在目录/a//b/中。

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

我们如何将PATH 设置为更喜欢/a/c1 而不是/b/c1/ 但同时/b/c2 而不是/a/c2

遗憾的是,没有办法直接实现这一点,因为我们只能在PATH 中指定目录。我们必须移动/重命名一些文件或创建符号链接并使用路径内的符号链接。一种可能的解决方案:

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

尾随的:/a:/b 在这里并不是必需的。我在假设 /a/b 包含比 c1c2 更多的可执行文件的情况下包含它们。

【讨论】:

很好的推论,但那部分应该属于指定的重复恕我直言。【参考方案2】:

确实,您可以通过实验很容易地发现,变量PATH 应该已经包含按该顺序查询的目录 列表。实际上,您应该已经发现在默认的PATH 中有/usr/local/bin/usr/bin,通常是这个顺序(尽管它们之间可能还有其他目录,当然它们周围还有更多目录)。

要检查您当前的 PATH 值,请尝试

echo "$PATH"

或者为了更易读的渲染

echo "$PATH//:/$'\n'"     # bash only

echo "$PATH" | tr ':' '\012'  # any POSIX system

如果您设法将您的 PATH 设置为无效值(这将导致不再找到 lscat 等简单命令,并产生 command not found 错误),您可以尝试

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

希望至少可以恢复基本功能,以便您可以使用 cp 或简单的系统编辑器恢复到原始、安全的系统默认设置 PATH

【讨论】:

POSIX 方式显示$PATH:IFS=:; for dir in $PATH; do echo "$dir"; done 这会破坏你的IFS。您可以将整个内容放在括号中以解决此问题。 unset IFS 完成后。这就是你使用 IFS 的方式。 如果您确定它之前没有设置为其他值,那么它可以工作。但在一般情况下你不能知道。 经验法则:不要对IFS的内容做任何假设。如果你使用它,设置它或重置它。

以上是关于PATH 是不是应该包含二进制文件的目录或完整路径?的主要内容,如果未能解决你的问题,请参考以下文章

libsqlplus.so:无法打开共享对象文件:即使 PATH 包含路径,也没有这样的文件或目录

获取Golang中给定文件路径的目录名称(不是路径)

./ 和 ~/ 之间的区别

[Linux] 更新PATH环境变量或默认执行文件搜索路径

VS2012中引用dll目录的配置方法转

path是啥意思啊?