脚本中调用脚本,有三种方式
1.fork
2.exec
3.source
需要用到的示例
a.sh
#!/bin/bash
if [ -n "$2" ];then
do_date=$2
else
do_date=`date -d "-1 day" +%F`
fi
echo "=======a.sh时间:$do_date======="
echo "a.sh===Pid:$$"
# export do_date
case $1 in
--sh)
sh b.sh $do_date
sh c.sh $do_date;;
--exec)
exec ./b.sh $do_date
exec ./c.sh $do_date;;
--source)
source b.sh $do_date
source c.sh $do_date;;
esac
echo "====a.sh执行完成========"
b.sh
#!/bin/bash
if [[ -n "$1" ]];then
do_date=$1
else
do_date=`date -d "-1 day" +%F`
fi
echo "=======b.sh时间:$do_date======="
echo "b.sh===pid: $$"
c.sh
#!/bin/bash
if [ -n "$1" ];then
do_date=$1
else
do_date=`date -d "-1 day" +%F`
fi
echo "=======c.sh时间:$do_date======="
echo "c.sh===Pid:$$"
fork
fork是最普通的一种调用方式,如果有执行权限,可以直接调用,如:要执行的脚本是 a.sh 在当前目录直接执行即可: ./a.sh,
如果没有执行权限,那么需要加上sh 或者 bash 。即:sh ./a.sh(ubuntu系统sh 默认调用dash,dash和bash是有区别的,最后说一下遇到的坑)。这种方式在调用时,会新起一个进程。所以它的执行流程会按照顺序依次执行。
执行流程:a.sh–>b.sh–>c.sh–> a.sh执行完成
结果:
可以看出a.sh 会启用一个进程,b.sh c.sh 分别会启用新的进程。
exec
在脚本中使用exec 调用另一个脚本,不会重新启动一个进程来执行,意味着 a.sh 和 b.sh 是同一个进程,但是exec执行完b.sh之后,进程就会结束。a.sh之后的代码不会在执行。
执行流程:
a.sh–>b.sh
结果:
source
在脚本中使用source调用另一个脚本,和exec相同,都是在同一个进程,但是source和exec的区别是source会执行完所有代码
执行流程:a.sh–>b.sh–>c.sh–>a.sh执行完成
结果:
问题
下面说一个sh 执行遇到的问题
当使用sh执行的时候,细心的同学已经发现了,b.sh中的打印的时间和其他的时间不同。而且执行还报错了:b.sh: 3: [[: not found。
我当时在项目中用到了脚本中调用脚本,用的就是第一种方法,而且是 sh执行的。我当时的需求是要把参数传到调用的脚本中,选择了第一种方法。但是为什么传进去参数会报错呢,然后我开始找原因。看了关于报错提示的文章 为什么[[ 会找不到?因为我用的是ubuntu系统,而ubuntu系统sh 默认用的是dash 。下图可以看到 sh 通过软连接 指向了dash
而 dash 和 bash 是有区别的:
bash: 支持[[ ]], 可实现正则匹配等强大功能
dash: 不支持[[ ]], 替代方法,采用外部命令
所以当我换成bash ok 问题成功解决。当然,也可以把b.sh中使用的 [[ ]] 换成 [ ] 也可以解决我这里的问题
想了解更多 dash 和 bash 区别,可以参考:https://www.cnblogs.com/macrored/p/11548347.html