为什么我们要使用./filename在Linux中执行文件?

为什么不像其他命令gccls等一样直接输入文件...

评论

第一行难道不能写成“为什么我们要使用./command_name在Linux中执行命令?”

user15760,否,因为我们喜欢在搜索引擎中可以发现的问题,并且并非所有有此问题的人都是天生的'nixsters(:

#1 楼

在Linux,UNIX和相关操作系统中,.表示当前目录。由于要在当前目录中运行文件,并且该目录不在$PATH中,因此需要./位来告诉Shell可执行文件在哪里。因此,./foo意味着运行此目录中的名为foo的可执行文件。

您可以使用typewhich来获取在$PATH中找到的所有命令的完整路径。

评论


在当前目录中执行程序是很常见的。为什么外壳也不能在其中搜索?它首先在。中搜索,然后在$ PATH中搜索。

–迈克尔
13年7月9日在22:14



还有一些别名可能会妨碍您,而不仅仅是$ PATH。

–user2485710
14-10-14在21:35

@Michael安全与理智:如果搜索到。首先,这将是一个安全问题,例如您或其他人可以替换ls(一个简单的病毒/木马:在其中用名为ls的可执行文件制作一个zip文件,当有人搜索时,他们运行此可执行文件,即… )。如果搜索到。最后,您可能会花很长的时间疯狂,不知道为什么程序无法运行(例如,您创建了一个名为test的程序,而不是运行程序,而是运行了系统测试程序。该程序不会产生任何输出)。

–ctrl-alt-delor
15年3月14日在18:24

它还可以确保,如果应用程序或脚本在路径中多次出现,则表示您正在执行要运行的版本(“。”目录中的该版本)。

– Jim2B
15年7月7日在18:43

@jcubic这是个坏主意。请参阅上面的评论。过去,DOS会在当前目录中进行搜索,而该行为会在Windows cmd上进行,这会带来很多安全问题。 MS在PowerShell中修复了该问题,现在您必须使用。\才能在当前目录中运行该程序

–phuclv
20 Mar 15'9:41



#2 楼

字面上的答案就像其他人一样:因为当前目录不在您的$PATH中。
但是为什么呢?简而言之,这是为了安全。如果您正在查找其他人的主目录(或/ tmp),并仅输入gccls,则想知道您正在运行的是真实版本,而不是恶作剧朋友编写的会擦除所有文件的恶意版本。另一个示例是test[,如果您的外壳没有内置命令,它们可能会覆盖外壳脚本中的命令。
.作为路径中的最后一个条目会更安全一些,但是其他利用它的攻击。一种简单的方法是利用常见的拼写错误,例如slls-l。或者,找到一个恰巧未在该系统上安装的通用命令-例如,vim,因为sysadmins键入该命令的可能性高于平均水平。
听起来是否太理论化了?它很大程度上是,但是它确实可以在现实中发生,尤其是在多用户系统上。实际上,这是该站点上的一个示例,其中管理员切换到用户的主目录,并发现ps被该名称的可执行文件掩盖。

评论


在PATH环境变量中只包含绝对路径。

– Ed Heal
15年8月6日在18:56

#3 楼

如果您要说的话,为什么一开始就需要./-这是因为(与Windows不同,)默认情况下,当前目录不是路径的一部分。如果您运行:

$ ls


您的外壳在PATH环境变量的目录中查找ls(请参见echo $PATH),然后运行第一个可执行文件ls发现。如果键入:

$ a.out


外壳程序也会这样做-但它可能找不到名为a.out的可执行文件。您需要告诉外壳程序a.out的位置-它在当前目录(。)中,然后路径是./a.out

如果您要问为什么它叫“ a.out”,那就是只是gcc的默认输出文件名。您可以使用-o命令行arg进行更改。例如:

$ gcc test.c -o test
$ ./test


评论


谢谢。我的疑问是,为什么您一开始就需要...。我使用了“。” (添加当前目录),但是为什么之后是“ /”呢?

– Renjith G
2010-11-30 8:35

/是Linux中的路径分隔符,因此您可以使用它将目录(。)与文件名(a.out)分隔开。没有它,您将拥有.a.out本身就是有效的文件名。 (尝试触摸.a.out; ls -lA来查看。)

–西蒙·惠特克(Simon Whitaker)
2010-11-30 8:37

这就是您在Unix中指定路径 / 的方式,因此您基本上是说在当前目录中执行一个文件,该文件由./test指示

–罗汉·蒙加(Rohan Monga)
2010-11-30 8:37

红帽Linux 9?是时候升级了!

–mattdm
2011-2-17在1:53

在Windows 10上,PowerShell现在是默认的外壳程序,它还要求./在当前路径中运行可执行文件。

–卡尔·沃尔什(Carl Walsh)
19年8月6日在2:59

#4 楼

您可以尝试将:.添加到$ PATH变量中。

尝试ALT + F2并键入:gksudo gedit /etc/environment(如果运行Linux / GTK,这是​​使用Ubuntu时的情况)。

但是,我强烈建议您不要这样做。不好,不好,不好。

您知道,自1970年以来,这种事情就一直这样。有一个原因,为什么当前目录未包含在$ PATH中。

.是当前目录

.something将是一个隐藏文件(键入“ ALT +”使它们出现在Nautilus中,或尝试使用“ ls -la”。您键入的内容以在当前目录中运行可执行文件someProgram.sh。

./someProgram.sh意味着您在当前目录中具有隐藏的可执行文件,这是个坏主意。

#5 楼

更完整的规则实际上是:如果路径中有任何斜杠/,请不要搜索PATH
在开始论证之前,您应该首先了解以下事实:运行以下任一命令:
bin/someprog

::
/bin/someprog
cd bin
./myexec

执行bin/someprog而不出于完全相同的原因搜索PATH变量:所有bin/someprog/bin/someprog./someprog都带有斜杠/
someprog本身没有斜线/,因此仅在PATH中进行搜索。
POSIX 7在以下位置指定了此规则:http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02 .html#tag_18_09_01_01

PATH
[...]如果所查找的路径名包含<slash>,则不应通过路径前缀进行搜索。

/ POSIX PATH规则的原理
假设正在运行:
someprog

将进行搜索:
相对于CWD首先
相对于PATH之后的

然后,如果您想从发行版中运行/bin/someprog,并且您执行了以下操作:
someprog

有时可以工作,但其他方法却会失败,因为您可能位于一个包含另一个不相关的目录中someprog程序。
因此,您很快就会发现这是不可靠的,并且当您要使用PATH时,最终将始终使用绝对路径,因此违反了PATH的目的。
这也是为什么在PATH中包含相对路径是一个非常糟糕的主意。我正在看着你,node_modules/bin。相反,假设正在运行:
./someprog

将搜索:

相对于PATH first
相对于CWD之后,如果您只是从git存储库下载了脚本someprog并想从CWD运行它,则您将无法确定这是将要运行的实际程序,因为也许您的发行版已经答:
/bin/someprog

去年圣诞节后喝了太多酒后安装的某些软件包中的某个路径在您的PATH中。
因此,再次,您将不得不始终使用相对于CWD的本地脚本运行具有完整路径的本地脚本,以了解您的运行状况:
"$(pwd)/someprog"

这也将非常烦人。
您可能会想出的另一个规则是:

相对路径仅使用PATH,绝对仅使用CWD

的路径,但这再次迫使用户始终对带有"$(pwd)/someprog"的非PATH脚本使用绝对路径。
/路径搜索规则为about问题提供了一个易于记住的解决方案:

斜杠:不要使用PATH

不斜杠:只使用PATH


,这样总是很容易知道什么您正在运行,这取决于当前目录中的文件可以表示为./somefilesomefile的事实,因此它对其中之一具有特殊的含义。
有时,它很小很烦人的是,您无法搜索相对于some/progPATH,但我看不出对此有更好的解决方案。