为什么要在bash中运行它,在可执行文件或脚本名之前需要。/(点斜杠)?

为什么要在bash中运行它,在可执行文件或脚本名之前需要。/(点斜杠)?,bash,shell,unix,command-line,Bash,Shell,Unix,Command Line,在bash中运行脚本时,我必须在开头编写/: $ ./manage.py syncdb 如果我没有,我会收到一条错误消息: $ manage.py syncdb -bash: manage.py: command not found 这是什么原因?我认为是当前文件夹的别名,因此这两个调用应该是等效的 我也不明白为什么在运行应用程序时不需要/,例如: user:/home/user$ cd /usr/bin user:/usr/bin$ git (运行时不使用/)因为在Unix上,当前目录通

在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
。如果当前目录在
路径中
,shell将尝试执行该目录中的
sl
程序(因为没有其他
sl
程序)。该
sl
程序可能是恶意的

它与
/
一起工作,因为包含
/
的命令名将直接用作文件名,从而禁止在
$PATH
中进行搜索。您可以使用完整路径实现完全相同的效果,但是
/
更短,更易于编写

编辑


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

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


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

当脚本不在其所需的路径中时。有关更多信息,请阅读

当您包含“.”时,实际上是为可执行bash脚本提供了“完整路径”,因此您的shell不需要检查path变量。如果没有“.”,您的shell将查看PATH变量(您可以通过运行
echo$PATH
查看您键入的命令是否存在于您路径上的任何文件夹中。如果不存在(与manage.py一样)它表示找不到文件。将当前目录包含在路径中被认为是一种不好的做法,这里对此进行了合理的解释:

on*nix,与Windows不同,当前目录通常不在
$PATH
变量中。因此,在执行命令时不会搜索当前目录。您不需要
/
用于运行应用程序,因为这些应用程序位于$PATH中;它们很可能位于
/bin
/usr/bin
当bash解释命令行时,它会在环境变量
$PATH
中描述的位置查找命令。要查看命令类型:

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

PATH=$PATH:.
此行将当前目录添加到
$PATH
中,以便执行以下操作:

manage.py syncdb
不建议使用,因为它存在安全问题,而且您可能会有奇怪的行为,因为您所在的目录不同:)

避免:

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


只有我的两分钱。

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

./executable
如果你跑的话你会得到什么

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

通过运行

哪个可执行文件


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

所有这些都对这个问题有很好的答案,是的,这只适用于在当前目录下运行它,除非包含绝对路径。见下面我的样品

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

POSIX路径规则的基本原理

规则在:中提到,但我想更详细地解释为什么我认为这是一个好的设计

首先,该规则的明确完整版本是:

  • 如果路径包含
    /
    (例如
    /someprog
    /bin/someprog
    /bin/someprog
    ):使用CWD,而不使用路径
  • 如果路径不包含
    /
    (例如
    someprog
    ):使用路径而不使用CWD
现在,假设运行:

someprog
./someprog
将搜索:

  • 相对于CWD优先
  • 相对于路径之后
然后,如果您想从发行版运行
/bin/someprog
,那么:

someprog
它有时会工作,但另一些则会失败,因为您所在的目录可能包含另一个不相关的
someprog
程序

因此,您很快就会了解到这是不可靠的,当您想要使用PATH时,您最终将始终使用绝对路径,因此无法达到PATH的目的

这也是为什么在你的路径中有相对路径是一个非常糟糕的主意。我很高兴

相反,假设
./someprog
/bin/someprog
"$(pwd)/someprog"