关于shell:为什么在可执行文件或脚本名称之前需要./(dot-slash)才能在bash中运行它?

Why do you need ./ (dot-slash) before executable or script name to run it in bash?

在bash中运行脚本时,我必须在开头写./

1
$ ./manage.py syncdb

如果我不这样做,我收到一条错误消息:

1
2
$ manage.py syncdb
-bash: manage.py: command not found

这是什么原因? 我认为.是当前文件夹的别名,因此这两个调用应该是等效的。

我也不明白为什么我在运行应用程序时不需要./,例如:

1
2
user:/home/user$ cd /usr/bin
user:/usr/bin$ git

(没有./运行)


因为在Unix上,通常当前目录不在$PATH中。

键入命令时,shell会查找由PATH变量指定的目录列表。当前目录不在该列表中。

不在该列表上具有当前目录的原因是安全性。

假设你是root并进入另一个用户的目录并输入sl而不是ls。如果当前目录在PATH中,shell将尝试在该目录中执行sl程序(因为没有其他sl程序)。该sl程序可能是恶意的。

它适用于./,因为POSIX指定包含/的命令名称将直接用作文件名,从而禁止在$PATH中搜索。您可以使用完整路径获得完全相同的效果,但./更短且更容易编写。

编辑

那个sl部分只是一个例子。按顺序搜索PATH中的目录,并且当执行程序匹配时。因此,根据PATH的外观,键入正常命令可能会或可能不足以在当前目录中运行该程序。


当bash解释命令行时,它会在环境变量$PATH中描述的位置查找命令。看它的类型:

1
echo $PATH

您将有一些以冒号分隔的路径。正如您将看到的当前路径.通常不在$PATH中。因此,如果Bash位于当前目录中,则无法找到您的命令。您可以通过以下方式进行更改:

1
PATH=$PATH:.

此行添加$PATH中的当前目录,以便您可以执行以下操作:

1
manage.py syncdb

不推荐它,因为它有安全问题,而且你可能有奇怪的行为,因为.因你所在的目录而异:)

避免:

1
PATH=.:$PATH

因为你可以"掩盖"一些标准命令并打开安全漏洞的大门:)

只是我的两分钱。


当shell查看$PATH环境变量以查找脚本时,将无法找到您的主目录中的脚本。

./表示'查看当前目录中的脚本,而不是查看$PATH中指定的所有目录。


当你包含'。'时你基本上给了可执行bash脚本的"完整路径",所以你的shell不需要检查你的PATH变量。没有'。'你的shell将查看你的PATH变量(你可以通过运行echo $PATH来查看你输入的命令是否存在于PATH的任何文件夹中。如果不存在(如manage.py的情况)它说它无法找到该文件。将当前目录包含在PATH中被认为是不好的做法,这在这里得到了相当好的解释:http://www.faqs.org/faqs/unix-faq/faq/part2 /section-13.html


在* nix上,与Windows不同,当前目录通常不在$PATH变量中。因此,执行命令时不会搜索当前目录。您不需要./来运行应用程序,因为这些应用程序位于$ PATH中;最有可能的是/bin/usr/bin


这个问题已经有了一些很棒的答案,但我想补充一点,如果你的可执行文件在PATH上,那么当你运行时输出会有很大的不同

1
./executable

如果你跑,你得到的

1
executable

(假设您遇到的错误消息是一个而不是另一个),那么问题可能是您的计算机上有两个不同版本的可执行文件:一个在路径上,另一个不在。

通过运行检查

可执行文件

1
whereis executable

它修复了我的问题...我有三个版本的可执行文件,其中只有一个是为环境正确编译的。


当脚本不在Path中时,它需要这样做。欲了解更多信息,请阅读http://www.tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_01.html


所有人都对这个问题有很好的答案,是的,这只适用于在当前目录上运行它,除非你包含绝对路径。请参阅下面的示例。

此外,当我在子文件夹tmp2(/ tmp / tmp2)上执行命令并使用(双点斜杠)时,(点斜线)对我有意义。

样品:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[fifiip-172-31-17-12 tmp]$ ./StackO.sh

Hello Stack Overflow

[fifi@ip-172-31-17-12 tmp]$ /tmp/StackO.sh

Hello Stack Overflow

[fifi@ip-172-31-17-12 tmp]$ mkdir tmp2

[fifi@ip-172-31-17-12 tmp]$ cd tmp2/

[fifi@ip-172-31-17-12 tmp2]$ ../StackO.sh

Hello Stack Overflow

Current DirectoryWorking Directory之间存在差异,您可以轻松地在google上找到它。这就是你的manage.py syncdb没有按预期执行的原因。

当前目录:它是执行shell或父进程的目录。

1
you are right"."  is for current directory.

在基于UNIX的系统中,如果您的文件位于/data/myfile.out,那么您将通过forward slash"/"分隔的组件名遍历您的文件,因此如果"."是您当前的目录,那么您是否要访问(在您的案例中执行) )当前目录中的文件,您将不得不说./myexecutableFile.o。如果您的可执行文件位于当前目录的另一个文件夹中,那么您将执行类似./myFiles/myexecutableFile.o的操作。希望你得到我想要解释的内容。