许多人说,出于安全原因,当前目录不在变量中$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 会运行下面列表中第一个现有的对象。此列表根据您的情况量身定制。
ls
功能。ls
内置(通常ls
不是 Bash 中的内置命令;但由于 Bash 可以动态加载新的内置命令,因此您可以创建ls
内置命令)。ls
可执行文件,其完整路径名存储在哈希表中(如果过去某个时间ls
根据下一点找到了可执行文件并且仍然记住它,就会发生这种情况)。ls
可从 执行$PATH
。对于你的情况,顺序是:/usr/local/bin/ls
/usr/bin/ls
/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
。