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

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

键入程序名称(例如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 error。

使用./前置命令有效地说“忘记PATH,我希望你只查看当前目录”。

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

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

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

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

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

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

这样做的原因是简单的。

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

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

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

需要进行此分离以避免运行错误的文件。 即如果你的主目录中有一个名为ls的文件,它不在你的PATH中会阻止bash将它与真正的ls混淆。 PATH变量还定义搜索顺序:

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

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

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

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

    替代文字

您现在可以将文件复制到PATH中的任何目录,以查看其中的哪些目录 – 并且它们是基于每个用户设置的 – 键入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 ,则会运行它而不是驻留在/bin中的正确cat 。 您可以使用type catwhereis cat找到文件的位置。

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

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

解决方案1

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

  1. 只需~/.pam_environment添加到文件~/.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

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

现在,只要你在其他任何地方有另一个程序,让我们说你的桌面上的程序b.in ,你需要做的就是: ln -s /home/userName/Desktop/b.in /home/userName/bin ,你然后能够在没有./情况下运行它。

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

正如George在他的回答中所指出的,这有助于您注意到您在当前工作目录( pwd )中执行文件。

我记得很久以前就向老人提过这个问题了,他说我应该补充一下. 到我的路径,以便当我执行a.out它会在当前目录中查找并执行该操作。 在这种情况下,我不必做./a.out

但是,就个人而言,我建议反对它。 它从来没有发生在我身上,但是如果你在外星网络目录或其他东西上,那里存在一个名为ls的恶意可执行文件,那么就有了. 在你的道路上是一个非常糟糕的主意。 并不是说你会经常遇到这个问题,只是说。

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

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

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

我建议你创建一个名为“testbin”的新目录或类似的东西,并将它放在你的路径上,以保持现有的路径目录清洁。

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

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

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

与:

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

在前面的示例中,您通过目录及其sup-directories访问了文件位置,并使用“./”在当前目录中运行该文件。

在它之前的那个“ [root @ server~]#/ path / to / file / file.pl ”也会执行该文件,如果你懒得“cd”你的方式到文件位置。

它非常简单,有很多用途。

  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. . – 始终表示从当前目录执行。 并且..总是表示从前一个目录执行。