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

我正在尝试使用现有的代码库,但遇到了问题。 总之,我执行一个shell脚本(我们称之为A ),其第一个行为是调用另一个脚本( B )。 脚本B在我的当前目录(我正在使用的程序的要求)。 该软件的手册引用了bash ,但是A中的注释表明它是用ksh开发的。 我一直在bash运行。

A里面,执行B的行很简单:

 . B 

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

当我打电话没有点空间语法,即:

 ./A 

它总是错误,说它找不到文件B 我添加了pwdlswhoamiecho $SHELL ,并将echo $PATH行回显为A进行debugging,并确认B实际上就在那里,脚本运行时与我在命令提示符下的$SHELL相同,脚本是和我一样的用户,并且脚本和我一样具有相同的searchpath$PATH 。 我也validation,如果我这样做:

 . B 

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

 ./B 

相反,然后A执行成功。

同样,如果我用点空间语法执行A ,那么两者都是. B . B./B工作。

总结
./A仅在A包含./B语法时才有效。
. A . A./B. B . B语法。

我明白,使用点空间(即. A )语法执行时不会分叉到一个子shell,但我不明白这可能会导致我观察到的行为,因为该文件显然是在那里。 有什么我缺less的语法或父/子过程工作区的细微差别? 魔法?

更新1 :添加信息,指示脚本可能已经在ksh开发,而我正在使用bash
更新2 :添加检查来validation$PATH是相同的。

UPDATE3 :脚本说它是为ksh编写的,但是它在bash运行。 为了回应Kenster的回答,我发现那时正在运行bash -posix . B . B在命令行失败。 这表明命令行和脚本之间的环境差异在于后者在符合POSIX标准的模式下运行bash ,而命令行却不是。 仔细看,我在bash man页中看到这个:

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

Ashebang确实是#!/bin/sh

总而言之,当我运行没有点空间语法的A时,它分叉到自己的子shell,它是POSIX兼容模式,因为shebang#!/bin/sh (而不是,例如#!/bin/bash 。是导致A无法findB的命令行和脚本运行时环境之间的关键区别。

让我们从命令路径的工作原理和使用时间开始。 当你运行一个像这样的命令:

 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 . 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不存在,即使当前目录中有一个名为B的文件。 正如上面所讨论的那样,shell会搜索你的B的命令路径,因为B没有包含任何/字符。 搜索命令时,shell不会自动搜索当前目录。 它只搜索当前目录,如果该目录是命令路径的一部分。

总之, . B . B可能失败,因为你没有“。” (当前目录)在您的命令路径中,而试图源B的脚本假定“。” 是你的路径的一部分。 在我看来,这是脚本中的一个错误。 很多人跑没有“。” 在他们的道路上,脚本不应该依赖于此。

编辑:

你说这个脚本使用ksh ,而你正在使用bash 。 Ksh遵循POSIX标准 – 实际上,KSH是POSIX标准的基础 – 并且总是像我所描述的那样搜索命令路径。 Bash有一个叫做“POSIX模式”的标志,它控制着POSIX标准的严格程度。 当不在POSIX模式下 – 人们普遍使用它的方式 – 如果在命令路径中没有找到文件,bash将检查当前目录中的文件来源。

如果你要运行bash -posix并运行. B . B在这个bash实例中,你会发现它不起作用。