在bash中运行脚本时,我必须在开始处写./: />
$ ./manage.py syncdb


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

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

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


(无需./运行)

评论

这是到目前为止我遇到的最好的文档:linfo.org/dot_slash.html

#1 楼

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

当您键入命令时,shell将根据PATH变量指定查找目录列表。当前目录不在该列表中。

没有当前目录在该列表中的原因是安全性。

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

它可以与./一起使用,因为POSIX指定包含/的命令名将直接用作文件名,从而抑制了在$PATH中进行搜索。您本可以使用完整路径来获得完全相同的效果,但是./较短并且更容易编写。依次搜索sl中的目录,并在匹配时执行该程序。因此,根据PATH的外观,键入常规命令可能不足以在当前目录中运行该程序。

评论


您无需输错任何内容。用户可能刚刚下载了包含ls可执行文件的恶意软件包。

–朱利亚诺
2011年6月13日13:34

只是对所有人的注释,它说这仅在Unix而非Windows中,在Powershell中也是如此-您必须执行。\ my.bat等才能执行

– manojlds
2011年6月13日在22:16



@gaearon ergh,我说“不是别名”,当时应该是“严格是别名”。

–查尔斯·达菲(Charles Duffy)
2011年6月13日23:46

这是一个非常有用的解释。 20多年前,当我稍微使用DOS时,我认为CMD会检查当前目录,然后是PATH,因此Linux的行为不是我所期望的,但是这很有意义。

–TecBrat
2013年12月23日14:37在

@cnicutar:今天有趣的是,我发现有一个称为蒸汽机车的sl命令,尽管默认情况下不可用;-)

–blackSmith
2014年9月11日下午12:46

#2 楼

当bash解释命令行时,它将在环境变量$PATH中描述的位置中查找命令。要查看它,请输入:

echo $PATH


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

PATH=$PATH:.


此行在$PATH中添加当前目录,因此您可以执行以下操作:
不建议这样做,因为它存在安全性问题,而且您可能会有奇怪的行为,因为.随您所在的目录而异:)
manage.py syncdb


您可以“掩盖”一些标准命令并打开安全漏洞的门:)

#3 楼

当外壳程序通过查看环境变量$PATH来查找您的脚本时,找不到您的脚本(位于主目录中)。 ./'。
中指定的所有目录

#4 楼

当您包含“。”时您实质上是为可执行的bash脚本提供“完整路径”,因此您的shell不需要检查PATH变量。不带“。”您的外壳程序将在您的PATH变量中查找(通过运行echo $PATH可以查看您输入的命令是否位于PATH的任何文件夹中。如果不存在(与manage.py相同),它会说将当前目录包含在您的PATH中是一种不好的做法,这在以下位置已得到很好的解释: -13.html

#5 楼

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

#6 楼

这个问题已经有了一些很棒的答案,但是我想补充一下,如果您的可执行文件位于PATH上,并且在运行

./executable


到如果您运行


executable


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

通过运行

哪个可执行文件



whereis executable


它解决了我的问题...我有三个版本的可执行文件,其中只有一个针对环境正确编译。

#7 楼

/ POSIX PATH规则的原理

该规则在以下位置提到:为什么在可执行文件或脚本名称之前需要./(点斜杠)才能在bash中运行它?但我想更详细地解释为什么我认为这是一个好的设计。

首先,该规则的明确完整版本为:路径包含/(例如./someprog/bin/someprog./bin/someprog):使用CWD且PATH不为
如果路径不包含/(例如someprog):使用PATH且CWD不为

现在,假设正在运行:

someprog


将进行搜索:


相对于CWD优先


之后的PATH,然后,如果您想从发行版中运行/bin/someprog,并且您执行了以下操作:否则它将失败,因为您可能位于包含另一个不相关的someprog程序的目录中。因此,您很快就会知道这是不可靠的,并且最终在使用时将始终使用绝对路径想要使用PATH,因此违反了PATH的目的。

这也是为什么在其中使用相对路径您的PATH是一个非常糟糕的主意。我正在看着你node_modules/bin。相反,假设正在运行:

someprog


将搜索:


相对于PATH首先
相对于CWD之后,

然后,如果您只是从git存储库下载了脚本someprog并想从CWD运行它,则永远不会请确保这是将要运行的实际程序,因为也许您的发行版具有:去年圣诞节。

因此,再次,您将不得不始终使用具有完整路径的CWD相对于本地脚本运行本地脚本,以了解您的运行状况:

./someprog


也很烦人。

您可能会想出的另一条规则是:


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


,但是一次再次,这迫使用户始终对带有"$(pwd)/someprog"的非PATH脚本使用绝对路径。 br斜杠:请勿使用/

无斜杠:仅使用PATH


,这样一来,超级容易始终知道您的运行依赖于以下事实:当前目录中的文件可以表示为PATH./somefile,因此它给其中之一赋予了特殊含义。到somefile,但是我看不到更明智的解决方案。

#8 楼

如果脚本不在路径中,则需要这样做。有关更多信息,请阅读http://www.tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_01.html

评论


...仅供参考,在irc.freenode.org上的#bash中,我们正在不断纠正人们从TLDP(特别是Advanced Bash指南)中学到的误解。因此,引导人们去那里……可能并不理想。 (我们首选的入门文档是mywiki.wooledge.org/BashGuide)

–查尔斯·达菲(Charles Duffy)
2011年6月13日13:42

#9 楼

所有人都对这个问题有很好的答案,是的,这仅适用于在当前目录上运行它的情况,除非您包括绝对路径。

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

示例:

[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