为什么在当前目录中执行程序之前需要输入`。/`?


92

a.out使用Ubuntu终端执行C程序时,为什么我总是需要在./before之前键入a.out而不是仅仅编写a.out?有解决方案吗?




Answers:


119

当您键入程序名称时,例如a.out系统会在PATH中查找文件。在我的系统上,PATH设置为

/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

你的可能差不多。要检查,请输入echo $PATH终端。

系统按照给定的顺序浏览这些目录,如果找不到,则会产生command not found错误。

在命令前加上./有效的内容是“忘记PATH,我希望您仅查看当前目录”。

类似地,您可以通过在命令前添加相对或绝对路径来告诉系统仅查看其他特定位置,例如:

../表示在父目录中,例如在父目录中../hello查找hello。

./Debug/hello:“ hello在当前目录的Debug子目录中查找。”

/bin/ls:“ ls在目录中查找/bin

默认情况下,当前目录不在路径中,因为它被认为存在安全风险。请参阅为什么。默认不在路径中?关于超级用户的原因。

可以将当前目录添加到您的PATH中,但是由于链接问题中给出的原因,我不建议这样做。


25
这个。+1 由于此答案中提到的安全风险,请勿添加.到您的内容中PATH(如当前其他两个答案所示)。
2013年

8
还可能需要注意的是,这里没有什么特别的.,您可以使用完整路径或相对路径指向可执行文件,例如,/home/user/foo/a.out./build/a.out
–tobyodavies 2013年

@tobyodavies; 实际上这.很特别,因为它的意思是“我的当前目录”,因此可以是用户使用读取和执行特权自行找到的任何目录。这可能比添加特定的完全限定路径更危险。
沃伦·希尔

@WarrenHill在考虑将其添加到您的路径时,是的,它是完全不同的。然而在bash语法方面,.拥有无特殊地位,它只是你同样可以用开始的路径/,并./blah会用很好的工作catgrep作为一个bash提示。
tobyodavies

@tobyodavies:好的,我已经编辑了答案,以包括您的观点。
沃伦·希尔

24

这样做的原因是简单的。

假设您有一个与当前目录中的应用程序名称相同的命令。然后在外壳中运行该命令将调用您的应用程序,而不是内置命令。如果没有其他问题,这将是一个安全问题。

通过要求./在前面使用,shell知道您要使用给定名称而不是该名称的内置命令来执行应用程序。


1
您的解释具有误导性,外壳程序中的内置命令与可通过PATH变量访问的可执行文件之间存在差异。事实上,您的回答越多,我阅读的感觉就越不正确。
艾哈迈德·马苏德

16

./执行不在your中$PATH的文件,而是执行当前目录中的文件(或通过./home/stefano/script.sh)。现在,PATH是一个环境变量,包含bash可以在其中查找可执行程序的所有位置,而没有完整的(绝对)路径。

为了避免运行错误的文件,需要进行此分隔。也就是说,如果您ls的主目录中有一个名为的文件,那么该文件不在您的PATH中将防止bash将其与real混淆ls。PATH变量还定义了搜索顺序:

  • 当您运行命令或程序尝试进​​行exec系统调用(内核的一种特殊方法,即如何启动程序)时,系统将通过PATH中的每个目录来查找文件。一旦找到该程序,即使它位于多个目录中,搜索也会中断,并且运行找到的第一个程序。

要运行文件,您需要在权限中设置可执行文件位:

  • 由于您已经在命令行中,因此只需键入即可chmod +x finename

  • 或者,您可以通过右键单击文件并选择“ 属性”来设置权限:

    替代文字

现在,您可以将文件复制到PATH中的任何目录中,以查看其中有哪些目录-并且它们是按用户设置的-type echo $PATH

stefano@3000-G530:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

如果您创建一个可执行文件,cat并移动它/usr/local/sbin,它运行,而不是正确的cat,它驻留在/bin。您可以使用type cat和查找文件的位置whereis cat


2
需要注意的一件事:他的问题似乎表明他已经编译了某些东西并将其链接到gcc,这会自动设置执行位。
内森·奥斯曼

12

为什么./在执行程序之前需要输入?

在终端中,每当您键入应用程序的名称时,假设gedit,终端将在包含应用程序(应用程序的二进制文件)的某些(预定义)目录中查找。这些目录的名称包含在名为的变量中PATH。您可以通过执行来查看此变量中的内容echo $PATH。看到那些目录以:?分隔。这些都是终端会在搜索,如果你只需要输入目录geditnautilusa.out。如您所见,a.out程序路径不存在。当您这样做时./a.out,您要告诉终端“在当前目录中查找并运行a.out,而不要进入PATH

解决方案1

如果您不想./每次都输入,则需要在中添加a.out的目录$PATH。在以下说明中,我将假定到的路径a.out/path/to/programs/,但是您应将其更改为实际路径。

  1. 只需将以下行添加到文件末尾~/.pam_environment

    PATH DEFAULT=${PATH}:/path/to/programs

    资料来源:持久性环境变量

  2. 注销并重新登录。现在,您可以在a.out没有./任何目录的情况下运行。

如果您在其他目录中有其他程序,则只需将其添加到上面的行中即可。但是,我建议您使用一个名为“ myPrograms”的目录,并将所有程序放在该目录下。

解决方案2

注意:更改userName为实际的Ubuntu用户名。

如果您要运行其他程序怎么办?它们都在不同的文件夹中吗?好的,“更有条理”的解决方案是bin在您的主目录下创建一个文件夹,并在该文件夹下添加符号链接(快捷方式)。这是如何做:

  1. mkdir /home/userName/bin

    • 这将bin在您的主目录下创建文件夹。
  2. ln -s /path/to/programs/a.out /home/userName/bin

    • 这将a.out在下创建您的程序的“符号链接”(基本上是快捷方式)bin
  3. 注销并重新登录。现在,您可以在a.out没有./任何目录的情况下运行。

现在,只要您在其他任何地方有另一个程序,b.in就可以在桌面上说该程序,您所需要做的就是:ln -s /home/userName/Desktop/b.in /home/userName/bin,然后您就可以运行该程序了./

注意:由于@Joe的注释,在进行备份时,必须专门处理符号链接。默认情况下,rsync根本不处理它们,因此在还原时,它们不存在。


1
如果很少使用,这是一个方便的技巧。大量使用它会使您的系统执行其他人不会期望的事情。另外,进行备份时,必须特别处理符号链接。默认情况下,rsync根本不处理它们,因此还原时它们不存在。
2013年

1

正如George在回答中指出的那样,这可以帮助您注意在当前工作目录()中执行文件pwd

我记得很久以前曾对我的上级老师问过这个问题,他说我应该添加.到我的路径中,这样当我这样做时,a.out它会在当前目录中查找并执行。在这种情况下,我不必做./a.out

但是,就个人而言,我建议不要这样做。这从来没有发生过,但是,如果您位于外部网络目录之类的目录中,并且ls存在一个名为的恶意可执行文件,那么.在您的路径中走是个非常糟糕的主意。并不是说您会经常遇到这个问题。


好的,斯特凡诺(Stefano)通过了他的答案来包含此信息:)
Shrikant Sharat 2010年

3
我完全不同意加入.$PATH。非常危险的主意。
内森·奥斯曼

1

除了其他答案之外,这里的基本部分man bash也能很好地说明这一点:

命令执行
       将命令拆分为单词后,如果它导致简单
       命令和可选参数列表,以下操作是
       采取。

       如果命令名称不包含斜杠,则shell尝试查找
       它。如果存在该名称的shell函数,则该函数为
       如上文“功能”中所述调用。如果名称不匹配
       函数,shell在shell内置列表中搜索它。如果
       找到一个匹配项,即调用了内置函数。

       如果名称既不是外壳函数也不是内置函数,并且不包含
       斜杠,bash在PATH的每个元素中搜索目录配置
       用该名称保存一个可执行文件。

0

当您运行一个为您所熟知且特定的程序(例如您自己的程序)时,“ ./”才有意义。该程序必须存在于当前目录中。当您运行$ PATH中某个位置的标准命令时,“ ./”没有任何意义。命令“哪个运行命令”告诉您该运行命令在$ PATH中的位置。


0
$ gcc hello.c -o /path/to/someplace/hello

将在某个位置生成可执行文件。如果该位置在您的路径上,则可以运行该文件。如果您想为动作“使用gcc编译此源代码并将可执行文件放置在路径上的某个位置”创建标签,则可以编写脚本

我建议您创建一个名为“ testbin”或类似名称的新目录,并将其放在路径中,以保持现有路径目录的整洁。


0

./消除了不必要的路径搜索。./强制仅在当前目录中搜索。如果我们不给./,然后它会搜索各种路径设置到系统一样/usr/bin/usr/sbin/等等。


0

“ ./”表示您要在当前目录中执行文件,它是键入整个路径的快捷方式,例如:

[root@server ~]#/path/to/file/file.pl

与:

[root@server file]#./file.pl

在上一个示例中,您遍历了目录及其子目录到文件位置,并使用“ ./”在当前目录中运行文件。

如果您懒于“ cd”到文件位置,则它前面的[root @ server〜]#/ path / to / file / file.pl也将执行该文件。


-4

这很简单,有很多用途。

  1. 当安装了同一应用程序的多个版本时,它将在不同的路径中可用,但是可以在中创建指向二进制文件的软链接/usr/bin。例如,安装了Python 2.7,Python 2.6,但/ usr / bin / python-> python2.7 / usr / local / bin / python-> python2.6

如果您在路径中/usr/local/bin并执行Python,它将始终执行Python 2.7。指定.将采用当前文件夹的可执行文件。

  1. .-始终代表从当前目录执行。并且..始终意味着从上一个目录执行。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.