使用点空间与点斜杠执行文件

时间:2014-06-18 16:29:41

标签: linux bash shell operators ksh

我正在尝试使用现有的代码库但遇到了问题。简而言之,我执行一个shell脚本(让我们称之为A),其第一幕是调用另一个脚本(B)。脚本B位于我当前的目录中(我正在使用的程序的要求)。该软件的手册引用了bash,但A中的评论表明它是在ksh中开发的。到目前为止,我一直在bash开展工作。

A内,执行B的行只是:

. B

它使用“点空间”语法来调用程序。它不像sudo那样做任何不寻常的事情。

当我在没有点空格语法的情况下调用A时,即:

./A

总是错误,说它无法找到文件B。我将pwdlswhoamiecho $SHELLecho $PATH行添加到A以进行调试并确认B是事实上,在那里,脚本运行时与我在命令提示符下的$SHELL相同,脚本与我的用户相同,并且脚本与我具有相同的搜索路径$PATH做。我还验证了我是否:

. B

在命令行,它工作得很好。但是,如果我将A内的语法更改为:

./B

相反,然后A成功执行。

同样,如果我使用点空间语法执行A,那么. B./B都可以正常工作。

综述
仅当./A包含A语法时,./B才有效 . A适用于A语法的./B. B

据我所知,使用点空间(即. A)语法执行时不会分支到子shell,但我不知道如果文件显然就在那里,这会导致我观察到的行为。对于语法或父/子进程工作空间的细微差别,我有什么遗漏吗?魔法?

UPDATE1 :添加了一些信息,表明该脚本可能是在ksh中开发的,而我正在使用bash
UPDATE2 :添加了检查以验证$PATH是否相同。

UPDATE3 :脚本说它是为ksh编写的,但它在bash中运行。在回答Kenster的回答时,我发现在命令行运行bash -posix然后. B失败。这表明命令行和脚本之间的环境差异是后者在POSIX兼容模式下运行bash,而命令行则不是。仔细观察,我在bash man页面中看到了这一点:

  

当调用sh时,bash在读取启动文件后进入posix模式。

shebang的{​​{1}}确实是A

总之,当我在没有点空间语法的情况下运行#!/bin/sh时,它会分支到它自己的子shell,因为Ashebang,所以它处于POSIX兼容模式(而不是,例如,#!/bin/sh。这是命令行和脚本运行时环境之间的关键区别,导致#!/bin/bash无法找到A

1 个答案:

答案 0 :(得分:22)

让我们从命令路径的工作原理以及何时使用它开始。当您运行如下命令时:

ls /tmp

此处ls不包含/字符,因此shell会搜索命令路径中的目录(PATH环境变量的值)以查找名为ls的文件。如果找到一个,则执行该文件。如果是ls,则通常位于/bin/usr/bin,这两个目录通常位于您的路径中。

在命令字中使用/发出命令时:

/bin/ls /tmp

shell不会搜索命令路径。它专门查找文件/bin/ls并执行该文件。

运行./A是运行名称中包含/的命令的示例。 shell不搜索命令路径;它专门查找名为./A的文件并执行它。 ""是您当前工作目录的简写,因此./A指的是应该位于当前工作目录中的文件。如果该文件存在,它将像任何其他命令一样运行。例如:

cd /bin
./ls

可以运行/bin/ls

正在运行. A采购文件的示例。源文件必须是包含shell命令的文本文件。它由当前shell执行,无需启动新进程。找到源文件的方式与找到命令的方式相同。如果文件名包含/,则shell将读取您指定的特定文件。如果文件的名称不包含/,则shell在命令路径中查找它。

. A        # Looks for A using the command path, so might source /bin/A for example
. ./A      # Specifically sources ./A

因此,您的脚本会尝试执行. B并且无法声明B不存在,即使您当前有一个名为B的文件目录。如上所述,shell将搜索B的命令路径,因为B不包含任何/字符。搜索命令时,shell不会自动搜索当前目录。它只搜索当前目录,如果该目录是命令路径的一部分。

简而言之,. B可能会失败,因为你没有"。"您的命令路径中的(当前目录),并且尝试源B的脚本假定"。"是你的道路的一部分。在我看来,这是脚本中的一个错误。很多人没有"。#34;在他们的道路上,剧本不应该依赖于此。

编辑:

当您使用ksh时,您说脚本使用bash。 Ksh遵循POSIX标准 - 实际上,KSH是POSIX标准的基础 - 并且总是按照我的描述搜索命令路径。 Bash有一个名为" POSIX模式"它控制着它遵循POSIX标准的严格程度。当不处于POSIX模式时 - 人们通常使用它 - 如果在命令路径中找不到该文件,bash将检查当前目录中是否有源文件。

如果您要在该bash实例中运行bash -posix并运行. B,您会发现它无法正常工作。