为什么默认路径中有 . ?

为什么默认路径中有 . ?

许多人说,出于安全原因,当前目录不在变量中$PATH,并且 Linux 不会在当前目录中查看该目录中是否有可用的特定命令。但我确实cd /usr/bin这样做了ls,并且效果很好;我也这样做了,echo $PATH并且输出包含/usr/bin

您应该注意到,出于安全原因,当前目录不在变量中$PATH,并且 Linux 不会在当前目录中查找该目录中是否有可用的特定命令。

Sander van Vugt 撰写的 Red Hat® RHCSATM/RHCE® 7 认证指南

为什么我可以ls在 内跑步/usr/bin

答案1

linux 不会在当前目录中查找特定命令是否可从该目录使用

确实如此,但查看中提到的所有目录$PATH,即使您此刻可能位于这样的目录中。

换句话说,如果.不在你$PATH没关系无论您身在何处,它都会始终搜索相同的目录以查看是否有特定的命令可用。

答案2

其他答案很好,但评论中的讨论表明更广泛的解释可能会有用。

这个文件描述了符合 POSIX 标准的 shell 应按什么顺序搜索命令。它非常通用,不是最容易理解的。我们不必分析这个高度抽象的过程,而是看看真正的 shell 是如何运作的。

假设

  • $PATH看起来像这样:/usr/local/bin:/usr/bin:/bin
  • 你在 Bash 中;
  • 您输入ls并点击Enter
  • 没有ls 别名这会将命令更改为其他内容ls

ls然后 Bash 会运行下面列表中第一个现有的对象。此列表根据您的情况量身定制。

  1. ls功能。
  2. ls内置(通常ls不是 Bash 中的内置命令;但由于 Bash 可以动态加载新的内置命令,因此您可以创建ls内置命令)。
  3. ls可执行文件,其完整路径名存储在哈希表中(如果过去某个时间ls根据下一点找到了可执行文件并且仍然记住它,就会发生这种情况)。
  4. ls可从 执行$PATH。对于你的情况,顺序是:
    1. /usr/local/bin/ls
    2. /usr/bin/ls
    3. /bin/ls

请注意,过程中没有./ls;也没有在任何时候考虑您的当前工​​作目录,尤其是它与中的条目不匹配$PATH

现在这个声明

Linux 不会在当前目录中查找特定命令是否可从该目录使用

./ls仅表示上述列表中没有硬编码。如果您$PATH包含.

出于安全原因,当前目录不在$PATH变量中

我稍后会在答案中解释这些原因。你仍然可以自己添加.$PATH在这种情况下,./ls它将作为 4.x 条目出现在列表中。与 Windows 相比,Windows 会ls在当前工作目录中查找不管是否在内$PATH。如果 Linux 也这么做,那么总是./ls在我们列表的第 3 点之上的某处进行硬编码。

如果你当前的工作目录是,/usr/bin并且列表显示ls应该解析为/usr/bin/ls,那么从技术上讲它是相同的可执行文件,./ls但是

  • shell 从不使用文字./ls路径,因此程序产生/usr/bin/ls
  • 事实上你/usr/bin身处没有什么
  • 事实/usr/bin$PATH很多

但是如果你在then.中的第一个条目是$PATH

  • shell 将使用文字./ls路径;
  • 你加入/usr/bin意味着很多
  • 事实/usr/bin$PATH没有什么

在两种情况下,最终运行的是同一个可执行文件,但是 shell 以不同的方式获取它。

还值得注意的是,“我当前的工作目录在我的$PATH”或“我在我的目录中$PATH”这样的语句并不能说明全部情况。它们可能意味着:

  • /some/particular/directory在我的$PATH,我/some/particular/directory现在在”

或者

  • “文字.条目在我的$PATH”。

如图所示,两种情况有所不同。


看起来你ls只是因为碰巧在它的目录中而希望不会被找到。嗯,这会很不方便,而且没有任何安全优势。.在一般命令搜索序列中没有固定步骤以及没有的.主要安全原因$PATH这个 UNIX 常见问题解答

.考虑一下在中第一个条目为 的情况下会发生什么PATH。假设您当前的目录是可公开写入的目录,例如/tmp。如果恰巧有/tmp/ls其他用户留下了一个名为 的程序,而您输入了ls(当然,打算运行正常/bin/ls程序),您的 shell 将改为运行./ls,即其他用户的程序。不用说,运行这样的未知程序的结果可能会让您大吃一惊。

/usr/bin/ls仅仅因为你在 而禁止它是没有意义的/usr/bin。如果ls存在恶意的,你可能已经在另一个目录中工作时运行了它,或者你最终会在另一个目录中工作时运行它。


总结

总而言之,ls在您的示例中,它之所以有效是因为/usr/bin/ls找到了 ,而不是./ls。后一个路径解析为前一个路径这一事实并不重要,因为后一个路径首先不会被使用。它之所以没有被使用是因为“Linux 不会在当前目录中查找……”(意思是它不会在 中查找.)。但它确实会查找/usr/bin,因为它在您的 中$PATH

相关内容