在同一个文件夹下有两个脚本。a.sh和b.sh,脚本内容例如以下:

a.sh:

echo "test for a"
source b.sh

b.sh:

echo "test for b"

使用bash a.sh 返回正确结果。

而使用sh a.sh返回结果例如以下:

test for a

a.sh: line 2: source: b.sh: file not found

明显脚本运行过程中。没有找到文件b.sh,将a.sh脚本内容改动为例如以下:

echo "test for a"
source ./b.sh

再次使用sh a.sh 又能够正常运行了,这是为什么呢?

问题就出在sh与bash运行脚本的差别。

  首先要明白重要的一点:/bin/sh 尽管是/bin/bash的软连接,但这个软连接非常特殊,它并不仅仅仅仅是一个链接,sh不等于bash。假设你在CentOS下使用man sh能够找到这句话:

Bash can be configured to be POSIX-conformant by default.

这说明sh 等于 bash -posix 也就是说使用sh来运行一个脚本,所以使用sh a.sh的效果等同于bash -posix a.sh,尽管大部分情况下等于使用bash来运行脚本,但启用了bash的posix模式,也能够理解为posix标准。

那么就要遵循这个标准下的要求。

如今来man bash在关于source命令的文档中找到这么一句话:

When bash is not in posix mode, the current directory is searched if no file is found in PATH.

假设bash不是运行在posix模式下,当文件名称最为source的參数系统假设在PATH中,也就是系统变量中找不到这个文件时会在当前文件夹下查找这个文件。

所以在不使用posix模式的情况下 a.sh脚本中的source b.sh不会出错,由于即使在PATH中找不到。也会在当前文件夹中进行查找。但假设使用了posix模式,能够在google中找到关于bash posix mode的内容。当中有一条:

The . and source builtins do not search the current directory for the filename argument if it is not found by searching PATH.

.也就是source这样的内建命令在使用文件名称作为參数时,假设在PATH中无法找到。将不会在当前文件夹自己主动进行查找。

这就是问题的关键。使用了sh 运行a.sh,脚本中source b.sh中的b.sh既不会在PATH中被找到也不会在当前文件夹下被找到,那么bash仅仅会返回

b.sh: file not found

但假设a.sh写成这样 source ./b.sh

这就不一样了,这等于给source提供了一个该文件的路径,尽管是相对路径,但bash是能够依据脚本本身运行的位置来找到b.sh的,所以就不会出错了。

总结:所以普通情况下。在Linux中运行一个bash的脚本。我们都会使用bash去运行。就是为了避免这样的奇怪问题的产生。

关于bash posix mode的相关信息你能够在这里找到:

http://structure.usc.edu/bash/bashref_6.html#SEC83

使用sh运行bash脚本的奇怪问题的更多相关文章

  1. Linux下运行bash脚本显示“: /usr/bin/env: "bash\r": 没有那个文件或目录

    用 ./ 运行bash脚本文件出现 报错信息 /usr/bin/env: "bash\r": 没有那个文件或目录 错误原因:这主要是因为bash后面多了\r这个字符的原因.在lin ...

  2. 实验楼-高级Bash脚本编程指南

    实验1.Bash介绍与入门 1.简介:Bash是一个为GNU计划编写的Unix shell,它是许多Linux平台默认使用的shell shell是一个命令解释器,是介于操作系统内核与用户之间的一个绝 ...

  3. source、sh、bash、./执行脚本的区别

    1.source命令用法: source FileName 作用:在当前bash环境下读取并执行FileName中的命令.该filename文件可以无"执行权限" 注:该命令通常用 ...

  4. linux 下source、sh、bash、./执行脚本的区别

    原文地址:http://blog.csdn.net/caesarzou/article/details/7310201 source命令用法: source FileName 作用:在当前bash环境 ...

  5. (转)source、sh、bash、./执行脚本的区别

    source.sh.bash../执行脚本的区别  原文:https://www.cnblogs.com/sparkbj/p/5976100.html 1.source命令用法: source Fil ...

  6. source sh运行脚本的差别

    主要有两种方式运行shell脚本 1)source test.bsh 2)sh test.bsh 1)souce运行脚本文件会在父程序中运行.各项动作都会在原本的bash内生效.运行过程不另开进程.脚 ...

  7. Bash脚本15分钟进阶指导

    首先声明这是网上摘来的.这里的技术技巧最初是来自谷歌的“Testing on the Toilet” (TOTT).这里是一个修订和扩增版本. 脚本安全 我的所有bash脚本都以下面几句为开场白: # ...

  8. 编写运行R脚本

    1.在后台运行R 1.1 创建file.R文件 1.2 在文件首行键入: #! /path/to/Rscript 1.3 在下面的行中,键入R代码 1.4 保存(记得有png(),jpeg(),... ...

  9. 【转】如何调试bash脚本

    本文转自:http://coolshell.cn/articles/1379.html Bash 是Linux操作系统的默认Shell脚本.Shell是用来处理操作系统和用户交互的一个程序.Shell ...

随机推荐

  1. Shell(三)流程控制

    Shell 流程控制 和Java.PHP等语言不一样,sh的流程控制不可为空,如(以下为PHP流程控制写法): <?php if (isset($_GET["q"])) { ...

  2. css样式中@import引入样式

    css样式中@import引入样式 学习了:http://www.cnblogs.com/zbo/archive/2010/11/17/1879590.html

  3. extjs grid 复制问题还有一种解决方式.

    之前的项目中尽管也常常使用到extjs,但也许是没有注意到,也也许是根本就没有须要用到这个功能. 前几天在和客户讨论需求时,客户说想要可以将gird表中的数据复制出来,当时没多想,感觉这功能extjs ...

  4. Python 获取Google+特定用户最新动态

    CODE: #!/usr/bin/python # -*- coding: utf-8 -*- ''' Created on 2014-8-28 @author: guaguastd @name: l ...

  5. 前端防止button被多次点击

    前端的部分逻辑有时候控制前端的显示.比方记录收藏数目等等.有时候多次反复点击会造成前端显示的bug.所以须要有部分逻辑推断去筛除掉反复多次的点击. 实现部分代码例如以下,主要是通过setTimeout ...

  6. BZOJ 3112 [Zjoi2013]防守战线 线性规划

    题意: 简单叙述: 一个长度为n的序列,在每一个点建塔的费用为Ci.有m个区间.每一个区间内至少有Dj个塔.求最小花费. 方法:线性规划 解析: 与上一题相似.相同使用对偶原理解题.解法不再赘述. 代 ...

  7. FPGA中亚稳态——让你无处可逃

    1. 应用背景 1.1         亚稳态发生原因 在FPGA系统中,如果数据传输中不满足触发器的Tsu和Th不满足,或者复位过程中复位信号的释放相对于有效时钟沿的恢复时间(recovery ti ...

  8. mobiscroll手机端插件 好用(时间、日历、颜色)

    http://demo.mobiscroll.com/range/rangepickertime/ 下载地址:http://download.mobiscroll.com/trial#/ios/dat ...

  9. Python一行代码获得IP地址

    比较靠谱的方法, 通过构造UDP包获得本机IP地址   python -c "import socket;print([(s.connect(('8.8.8.8', 53)), s.gets ...

  10. BZOJ 2127 二元关系

    题意: 思路: 先把所有的值加起来 最小割割哪儿 就代表那个地方不选 一减 剩下的就是 最大值了 //By SiriusRen #include <cstdio> #include < ...