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

Dan*_*mov 272 unix bash shell command-line

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

$ ./manage.py syncdb
Run Code Online (Sandbox Code Playgroud)

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

$ manage.py syncdb
-bash: manage.py: command not found
Run Code Online (Sandbox Code Playgroud)

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

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

user:/home/user$ cd /usr/bin
user:/usr/bin$ git
Run Code Online (Sandbox Code Playgroud)

(没有运行./)

cni*_*tar 293

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

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

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

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

它的工作原理是./因为POSIX指定包含a的命令名将/直接用作文件名,从而抑制搜索$PATH.您可以使用完整路径获得完全相同的效果,但./更短且更容易编写.

编辑

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

  • 你不需要输错任何东西.用户可能刚刚下载了包含"ls"可执行文件的恶意软件包. (47认同)
  • 只是给大家说一下这只是在Unix而不是Windows中,这在Powershell中是一样的 - 你必须执行`.\ my.bat`等来执行 (12认同)
  • 这是一个非常有用的解释.20多年前,当我使用DOS时,我认为CMD会检查当前目录,然后检查路径,因此Linux的行为不是我的预期,但它有很多意义. (4认同)
  • @cnicutar:有趣的是今天我发现有一个名为"蒸汽机车"的`sl`命令,但默认情况下不可用;-) (2认同)
  • 我不明白。如果可以通过“./”轻松绕过,这怎么可能是一种安全措施呢? (2认同)

neu*_*uro 50

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

echo $PATH
Run Code Online (Sandbox Code Playgroud)

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

PATH=$PATH:.
Run Code Online (Sandbox Code Playgroud)

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

manage.py syncdb
Run Code Online (Sandbox Code Playgroud)

这是推荐,因为它有安全问题,再加上你可以有奇怪的行为,因为.当你在目录变化:)

避免:

PATH=.:$PATH
Run Code Online (Sandbox Code Playgroud)

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

只是我的两分钱.


mdm*_*mdm 40

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

./说"看在我的脚本当前目录下,而不是在寻找中指定的所有目录$PATH".


Mar*_*ago 5

当您包含“。”时 您实质上是为可执行的bash脚本提供“完整路径”,因此您的shell不需要检查您的PATH变量。不带“。” 您的shell将查看您的PATH变量(可以通过运行echo $PATH以查看键入的命令是否位于PATH的任何文件夹中来查看。如果不存在(与manage.py相同),它会说找不到文件。将当前目录包含在PATH中是不正确的做法,在此处对此进行了很好的解释:http : //www.faqs.org/faqs/unix-faq/faq/part2/section- 13.html