Linux 一个 bash 和 sh 的问题?

evil850209 · 2013年04月17日 · 最后由 vincenttone 回复于 2013年04月19日 · 7637 次阅读

今天遇到一个 shell 的问题,此前是 Linux 小白。从学 ruby 后才开始用 Linux 的。有一个问题请教一下大家。

我有两个 sh 文件 A.sh 和 B.sh

A.sh 中代码如下

#! /bin/sh
echo 'start'
source B.sh
echo 'end'

B.sh 代码如下

echo 'I am in the b.sh'

运行 A.sh 后,如果没有#! /bin/sh会正常打印三句话,但现在是报错,说

line3 source: B.sh file not found.

后来查了一些资料,只是简单的知道了 sh 和 bash 是不太相同的。但为什么会报那个错呢?文件明明就在那里呀?

以前还听过一种叫 zsh 的东西,是吗?

额,经我测试,有没有 #! /bin/sh 都能打出三句话...... 测试环境是 OS X 下输入 sh 进入的 sh

我是在 Ubuntu 和 CentOS 中用测试的。

楼主代码经测试没有问题 楼主跑 A.sh 的时候当前目录是什么?是在 B.sh 所在目录吗?

@iBachue 是的

因为只是测试代码,所以肯定是放在同一个文件夹的。现在有一些遗留代码,都是用#! /bin/sh 这个 shell 运行的。

#4 楼 @evil850209 虽然在 Mac 下测试 不过看上去应该不会有问题 楼主可能要给个截图来看看是不是犯其他什么比较不容易发现的错误了。。

需要用 source ./B.sh

man bash 里的解释是:如果第一个参数不带 /, 就会从 $PATH 里面找 (类似于找可执行文件的逻辑). 带有 / 的话才会认为是相对/绝对路径。完整的解释可以看 man bash 测试环境是 Bash 4.2.045

需要指出的是,在 Ubuntu 上,/bin/sh 实际是软链接到 /bin/dash 的。CentOS 上是软链接到 /bin/bash 的。dash 是 POSIX shell 的实现,功能不如 Bash 丰富。但在 source 的逻辑上貌似没区别。

更正:发现自己机器上原来是有 dash 的。dash 里写 source ./B.sh 依然不管用。dash 的版本是 0.5.7

ubuntu 下运行和楼主一样的问题, #! /bin/sh 改为 #! /bin/bash 后正常 估计 bash 会找当前目录,sh 不一定。

ps,没记错的话基础是 sh,然后有优化包装成 bash,zsh 等多个不同的 shell。

@as181920 是呢,不知道是否能解决这个问题。在我们公司的测试环境中,这个 shell 脚本是能跑通的。不知道他们做了什么配置。

#9 楼 @evil850209 那就干脆写的安全一点,告诉 sh 到哪里找 B.sh,具体命令自己搜了:)

@as181920 关键是那个脚本我没有权限改,只能调用。所以想在自己的虚拟机中先测试一下,再给 QA 测试。结果出现这个问题了。

你把 line3 改成: source ./B.sh 或者换成 pwd,查看一下运行时的目录。

@zealinux 在代码里加入了 pwd 命令,显示如图

ls -al /bin/sh

看看这个结果在测试机器和部署机器结果一样么

我找到了一个解决的办法就是在 .bash_profile 中 PATH=$PATH:$HOME/bin:. 把当前目录加上,注意最后加了:.

#15 楼 @evil850209 不建议这么做。当你 cd 进入一个陌生的目录里,再不小心打错命令,而打出来的命令恰好是当前目录下的一个有害的可执行文件,就会出问题。当然这种情况出现的可能性也并不高。

我的建议是,找到这段代码的原始作者,麻烦他把脚本改成 source ./B.sh 的形式。

bash 什么版本?

看来 bash 是会寻找当前目录,而 sh 不会。 干脆把那句改成 source ./B.sh 好了。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号