为什么我们要用./filename
linux来执行文件呢?
为什么不像其他命令一样输入它等等gcc
......ls
答案1
字面答案正如其他人给出的那样:因为当前目录不在您的$PATH
.
但为什么?简而言之,就是为了安全。如果您正在查看其他人的主目录(或 /tmp),然后只输入gcc
或ls
,您想知道您正在运行真正的版本,而不是您的恶作剧朋友编写的会删除您所有文件的恶意版本。另一个例子是test
or [
,如果您的 shell 没有内置这些命令,它可能会覆盖 shell 脚本中的这些命令。
具有.
作为最后的进入你的路径会更安全一些,但是还有其他攻击利用了这一点。一种简单的方法是利用常见的拼写错误,例如sl
or ls-l
。或者,找到一个恰好未安装在该系统上的常用命令,vim
例如,因为系统管理员键入该命令的可能性高于平均水平。
这听起来太理论化了吗?它大部分是的,但它在现实中肯定会发生,特别是在多用户系统上。实际上,这是这个网站的一个例子管理员切换到用户的主目录,发现ps
被该名称的可执行文件屏蔽。
答案2
答案3
如果您的意思是,为什么在开头需要 ./ - 那是因为(与 Windows 中不同),默认情况下当前目录不是路径的一部分。如果你运行:
$ ls
ls
您的 shell在 PATH 环境变量中的目录中查找(echo $PATH
以查看它),并运行它找到的第一个可执行文件ls
。如果您输入:
$ a.out
shell 也会做同样的事情 - 但它可能找不到名为 a.out 的可执行文件。您需要告诉 shell a.out 在哪里 - 如果它位于当前目录 (.) 中,则路径为./a.out
.
如果您问为什么它被称为“a.out”,那只是 gcc 的默认输出文件名。您可以使用 -o 命令行参数更改它。例如:
$ gcc test.c -o test
$ ./test
答案4
更完整的规则实际上是:如果/
路径中有斜杠,则不搜索PATH
在我们深入探讨其原理之前,您应该首先了解这个事实:运行以下任一操作:
bin/someprog
或者:
/bin/someprog
或者:
cd bin
./myexec
执行时bin/someprog
无需搜索PATH
变量,原因完全相同:全部bin/someprog
,/bin/someprog
且其中./someprog
有斜杠。/
someprog
alone 没有斜杠/
,因此仅在 中搜索PATH
。
POSIX 7指定此规则于:http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01_01
小路
[...] 如果正在查找的路径名包含
<slash>
,则不应执行通过路径前缀的搜索。
/
POSIX PATH 规则的基本原理
假设运行:
someprog
会搜索:
- 首先相对于 CWD
- 相对于 PATH 之后
然后,如果你想/bin/someprog
从你的发行版运行,你就这样做了:
someprog
它有时会起作用,但有时会失败,因为您可能位于包含另一个不相关someprog
程序的目录中。
因此,您很快就会发现这是不可靠的,当您想要使用 PATH 时,您最终将始终使用绝对路径,从而违背了 PATH 的目的。
这也是为什么在 PATH 中包含相对路径是一个非常糟糕的主意。我是看着你,node_modules/bin
。
相反,假设运行:
./someprog
会搜索:
- 首先相对于 PATH
- 相对于 CWD 之后
然后,如果您刚刚someprog
从 git 存储库下载了一个脚本并想从 CWD 运行它,您将永远无法确定这是将运行的实际程序,因为您的发行版可能有:
/bin/someprog
这是你去年圣诞节后喝太多酒后安装的某个软件包的 PATH 路径。
因此,您将再次被迫始终使用完整路径运行相对于 CWD 的本地脚本,以了解您正在运行的内容:
"$(pwd)/someprog"
这也会非常烦人。
您可能会想出的另一条规则是:
相对路径仅使用 PATH,绝对路径仅使用 CWD
但这再次迫使用户始终对非 PATH 脚本使用绝对路径"$(pwd)/someprog"
。
路径/
搜索规则为 about 问题提供了一个简单易记的解决方案:
- 斜线:不使用
PATH
- 无斜线:仅使用
PATH
通过当前目录中的文件可以表示为 或./somefile
,这使得您可以非常轻松地始终了解您正在运行的内容,somefile
因此它赋予其中之一特殊的含义。
有时,有点烦人,您无法搜索some/prog
相对于 的内容PATH
,但我没有看到更明智的解决方案。