当在bash中运行脚本时,我必须在开始时编写./:

$ ./manage.py syncdb

如果我不这样做,我得到一个错误消息:

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

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

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

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

(运行时不需要。/)


当前回答

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

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

当前目录不在该列表上的原因是出于安全考虑。

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

它使用。/,因为POSIX指定包含/的命令名将直接用作文件名,抑制在$PATH中的搜索。为了达到完全相同的效果,您可以使用全路径,但是./更短,更容易编写。

EDIT

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

其他回答

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

./executable

和你逃跑后得到的那些人

executable

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

通过运行

这可执行

and

whereis executable

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

在*nix上,与Windows不同,当前目录通常不在$PATH变量中。因此,在执行命令时不搜索当前目录。你不需要。/来运行应用程序,因为这些应用程序在你的$PATH;它们很可能在/bin或/usr/bin中。

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

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

当前目录不在该列表上的原因是出于安全考虑。

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

它使用。/,因为POSIX指定包含/的命令名将直接用作文件名,抑制在$PATH中的搜索。为了达到完全相同的效果,您可以使用全路径,但是./更短,更容易编写。

EDIT

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

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

此外,当我在子文件夹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

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

echo $PATH

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

PATH=$PATH:.

这一行添加了当前目录在$PATH中,所以你可以这样做:

manage.py syncdb

不建议使用,因为它有安全问题,而且你可能会有奇怪的行为。取决于你所在的目录:)

避免:

PATH=.:$PATH

因为你可以“屏蔽”一些标准命令,并打开安全漏洞的大门:)

这只是我的个人意见。