【发布时间】:2014-08-09 01:18:30
【问题描述】:
我正在尝试使用现有的代码库,但遇到了问题。简而言之,我执行了一个shell 脚本(我们称之为A),它的第一步 是调用另一个脚本(B)。脚本B 在我的当前目录中(我正在使用的程序的要求)。该软件的手册引用了bash,但是A 中的cmets 建议它是在ksh 中开发的。到目前为止,我一直在bash 工作。
在A 内部,执行B 的行很简单:
. B
它使用“点空间”语法来调用程序。它并没有像sudo 那样做任何不寻常的事情。
当我在没有点空间语法的情况下调用A 时,即:
./A
总是出错,提示找不到文件B。我在A 中添加了pwd、ls、whoami、echo $SHELL 和echo $PATH 行以进行调试,并确认B 实际上就在那里,脚本以相同的@987654342 运行@ 因为我在命令提示符下,脚本和我是同一个用户,并且脚本和我有相同的搜索路径 $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 模式。
A 的 shebang 确实是 #!/bin/sh。
总之,当我在没有点空格语法的情况下运行A 时,它会分叉到它自己的子shell,它处于POSIX 兼容模式,因为shebang 是#!/bin/sh(而不是例如#!/bin/bash。这是导致A 无法找到B 的命令行和脚本运行环境之间的关键区别。
【问题讨论】:
-
B是否可执行?. B在技术上不是executeB,它是sources它。如果其中之一是ksh,请尝试使用ksh yourscript -
是的,
B是可执行的。我不清楚两者之间的区别,现在将阅读。 -
没关系,我看到
source是在同一个 shell 中运行某些东西的术语(和命令)。
标签: linux bash shell operators ksh