在同一个目录下有两个脚本,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. ProcessBuilder执行bash脚本

    我正在尝试从Java执行bash脚本,它返回错误/ bin / bash:'/ home / nika / NetBeansProjects / Parallel Framework / proces ...

  2. Linux中执行bash脚本报错/bin/bash^M: bad interpreter: No such file or directory

    问题描述:Linux中采用绝对路径执行Bash脚本,报错-bash: /home/xxx.sh: /bin/bash^M: bad interpreter: No such file or direc ...

  3. Ubuntu 执行 bash 脚本异常

    Ubuntu 执行 bash 脚本异常 文章目录 Ubuntu 执行 bash 脚本异常 执行报错 解决办法 参考 执行报错 [dev@my-ubuntu ~/packages/base_server ...

  4. linux 脚本加上行号,关于linux:如何在执行bash脚本时显示行号

    我有一个测试脚本,它有很多命令,会产生很多输出,我使用set -x或set -v和set -e,所以当出现错误时脚本会停止.但是,我仍然很难找到执行停止的行以定位问题.是否有一种方法可以在执行每一行之 ...

  5. windows执行bash脚本

    Windows执行shell脚本 1. 安装Git 2. 查看Git环境变量 右击电脑-属性-高级-高级系统设置 已设置环境变量 3. 打开Git bash 定位到sh文件所在目录,直接使用bash ...

  6. python:通过python脚本快速执行 bash 命令

    * git镇楼:git config --global core.filemode false* 实践出真知.虽然这个脚本代码量不大,但是也是经过3次修改才达到预期效果的. * 第一次写的时候,凭逻辑 ...

  7. Bash 脚本 set 命令教程

    http://www.ruanyifeng.com/blog/2017/11/bash-set.html set命令是 Bash 脚本的重要环节,却常常被忽视,导致脚本的安全性和可维护性出问题.本文介 ...

  8. 动态执行shell脚本

    文章目录 一.linux动态执行指定脚本 二.需求思路分析 ①我要做什么? ②先手动执行一遍流程 ③ 把执行命令记录下来 三.动态执行脚本 ①手动制作脚本 ②脚本升级 ③ 脚本截图 一.linux动态 ...

  9. python执行bash命令

    1.执行bash命令 import os os.system('ls -al') 2.执行bash脚本 os.system('sh ./test.sh') 3.脚本中带参数 arg1='111' ar ...

最新文章

  1. SIM PIN Lock
  2. Python_divmod() 函数简单说明
  3. #数据集#:并发脑电图、心电图和多剂量经颅电刺激行为的数据集
  4. python 利用多进程实现文件的拷贝
  5. linux 配置tensorflow 全过程记录
  6. SAS,SATA普及文档
  7. winform中键盘和鼠标事件的捕捉和重写(转)
  8. omnipay支付--支付宝支付
  9. Map-Reduce的逻辑过程
  10. java用正则表达式 编写简单词法分析器_500+ 精选 Java 面试题大放送
  11. linux中python编译器的配置_PyCharm配置虚拟编译环境(windows/linux通用版)
  12. Vue教程20:Vuex入门
  13. 能源路由器入门必读:面向能源互联网的架构和功能
  14. 7、python数据框重复值的查找和删除
  15. 什么是流程引擎,F2BPM
  16. Deep Learning with Pytorch 中文简明笔记 第七章 Telling birds from airplanes: Learning from images
  17. Lifeline功能介绍03——课堂信息的查询
  18. IP地址计算---子网掩码确定和子网划分等详解 (附常见相关习题)
  19. IT大侦“碳”:VxRail的可持续法宝
  20. openlayers在线地图:高德地图、天地图、谷歌、geoq(智图)

热门文章

  1. iftop命令命令详解
  2. 侯捷C++系统工程师
  3. 强化学习 11 —— REINFORCE 算法推导与 tensorflow2.0 代码实现
  4. c语言流控制(20180710)
  5. linux 查看文件创建时间
  6. 部署apollo-client到maven私服上时遇到的问题及排查过程
  7. SG函数和SG定理的运用
  8. Java 集成阿里大鱼平台短信服务发送验证码 --- 补齐注册部分
  9. git No tracked branch configured or branch doesn‘t exist
  10. FFT运算的加深理解——FFT的增益