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

Pra*_*kar 99 command-line bash

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

War*_*ill 126

当您键入程序名称时,例如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
Run Code Online (Sandbox Code Playgroud)

你的应该是类似的。要检查,请输入echo $PATH终端。

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

在命令前面./有效地表示“忘记 PATH,我希望您只查看当前目录”。

同样,您可以通过在命令前添加相对或绝对路径来告诉系统仅查看另一个特定位置,例如:

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

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

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

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

可以将当前目录添加到您的 PATH,但由于链接问题中给出的原因,我不推荐它。

  • 这个。+1 **不要**将`.`添加到您的`PATH`(如目前其他2个答案所建议的那样),因为此答案中提到了安全风险。 (26认同)
  • 可能还值得注意的是,这里的 `.` 没有什么特别之处,你可以使用可执行文件的完整或相对路径,例如 `/home/user/foo/a.out` 或 `./build/a.out ` (8认同)

Nat*_*man 27

这样做的原因是简单的。

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

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

  • 您的解释具有误导性,shell 中的内置命令与可通过 PATH 变量访问的可执行文件之间存在差异。事实上,你的答案我读得越多,感觉越不正确。 (2认同)

Ste*_*zzo 16

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

需要这种分隔以避免运行错误的文件。即,如果您ls在主目录中调用了一个文件,则它不在您的 PATH 中将防止 bash 将其与真正的ls. PATH 变量还定义了搜索顺序:

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

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

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

  • 或者您可以通过右键单击文件并选择Properties来设置权限:

    替代文字

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

stefano@3000-G530:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
Run Code Online (Sandbox Code Playgroud)

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

  • 需要注意的一件事:他的问题似乎表明他已经编译并链接了一些与`gcc` 的东西,它会自动设置执行位。 (2认同)

Ala*_*Ali 12

为什么./在执行程序之前需要打字?

在终端中,每当您键入应用程序的名称时,比方说gedit,终端将查看一些(预定义的)包含应用程序(应用程序的二进制文件)的目录。这些目录的名称包含在名为PATH. 您可以通过执行查看此变量中的内容echo $PATH。看到那些用:? 这些都是目录,终端会在搜索,如果你只需键入gedit,nautilus或a.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
    
    Run Code Online (Sandbox Code Playgroud)

    来源:持久性环境变量

  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根本不处理它们,因此当您恢复时,它们不存在。


归档时间:

查看次数:

134196 次

最近记录:

7 年,2 月 前