在Shell脚本中调用另一个脚本的三种方式讲解

先来说一下主要以下有几种方式:

  • fork: 如果脚本有执行权限的话,path/to/foo.sh。如果没有,sh path/to/foo.sh。
  • exec: exec path/to/foo.sh
  • source: source path/to/foo.sh

fork

fork 是最普通的, 就是直接在脚本里面用 path/to/foo.sh 来调用 foo.sh 这个脚本,比如如果是 foo.sh 在当前目录下,就是 ./foo.sh。运行的时候 terminal 会新开一个子 Shell 执行脚本 foo.sh,子 Shell 执行的时候, 父 Shell 还在。子 Shell 执行完毕后返回父 Shell。 子 Shell 从父 Shell 继承环境变量,但是子 Shell 中的环境变量不会带回父 Shell。

exec

exec fork 不同,不需要新开一个子 Shell 来执行被调用的脚本. 被调用的脚本与父脚本在同一个 Shell 内执行。但是使用 exec 调用一个新脚本以后, 父脚本中 exec 行之后的内容就不会再执行了。这是 exec source 的区别.

source

fork 的区别是不新开一个子 Shell 来执行被调用的脚本,而是在同一个 Shell 中执行. 所以被调用的脚本中声明的变量和环境变量, 都可以在主脚本中进行获取和使用。

其实从命名上可以感知到其中的细微区别,下面通过两个脚本来体会三种调用方式的不同:

第一个脚本,我们命名为 1.sh:

#!/usr/bin/env bash
A=1
echo "before exec/source/fork: PID for 1.sh = $$"
export A
echo "In 1.sh: variable A=$A"
case $1 in
    --exec)
        echo -e "==> using exec…\n"
        exec ./2.sh ;;
    --source)
        echo -e "==> using source…\n"
        . ./2.sh ;;
    *)
        echo -e "==> using fork by default…\n"
        ./2.sh ;;
esac
echo "after exec/source/fork: PID for 1.sh = $$"
echo -e "In 1.sh: variable A=$A\n"

第二个脚本,我们命名为 2.sh

#!/usr/bin/env bash
echo "PID for 2.sh = $$"
echo "In 2.sh get variable A=$A from 1.sh"
A=2
export A
echo -e "In 2.sh: variable A=$A\n"

注:这两个脚本中的参数 $$ 用于返回脚本的 PID , 也就是进程 ID。这个例子是想通过显示 PID 判断两个脚本是分开执行还是同一进程里执行,也就是是否有新开子 Shell。当执行完脚本 2.sh 后,脚本 1.sh 后面的内容是否还执行。

chmod +x 1.sh 2.sh 给两个脚本加上可执行权限后执行情况:

fork

fork 方式可以看出,两个脚本都执行了,运行顺序为1-2-1,从两者的PID值(1.sh PID=82266, 2.sh PID=82267),可以看出,两个脚本是分成两个进程运行的。

exec

exec 方式运行的结果是,2.sh 执行完成后,不再回到 1.sh。运行顺序为 1-2。从pid值看,两者是在同一进程 PID=82287 中运行的。

source

source方式的结果是两者在同一进程里运行。该方式相当于把两个脚本先合并再运行。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。如果你想了解更多相关内容请查看下面相关链接

(0)

相关推荐

  • 使用shell来发tcp包的方法

    经常用tcpdump抓包来倒腾和学习,但怎么触发tcp包呢?写一个客户端程序,然后朝server上发包,肯定可以,但还有更简单的方法: exec 8<>/dev/tcp/10.100.70.139/19006 echo -e "stats" >&8 用tcpdump抓包的结果为: xxxxxx$ sudo tcpdump -iany port 19006 -Xnlps0 tcpdump: verbose output suppressed, use -v or

  • 使用shell脚本来给mysql加索引的方法

    用shell脚本来给mysql加索引 刚好用到, mark一下: #! /bin/bash tb_base=tb_student_ arr=("0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "a" "b" "c" &q

  • linux shell之pushd、popd和dirs的使用讲解

    1 问题 我们有时候需要保存多个路径,上下键切换不方便,用cd-只能到上个目录,我们可以用dirs和pushd和popd 2 dirs.pushd.popd dirs: 这个命令显示栈里面所有的路径,一定会包含当前路径,常用参数如下 dirs -v 显示栈里面的所有路径和下标,通过下标,我们可以用pushd +下标到这个目录,然后popd+下标把这个路径在栈里面弹出来, dirs -c 清除栈里所有路径,但是当前路径不会删除 pushd:我们可以添加目录到栈(dirs)里面,比如添加当前目录pu

  • Shell中exit和return的区别讲解

    1.exit命令 exit命令是Shell内建命令,用于退出当前Shell进程.使用格式如下: exit [<n>] 可以指定退出状态n,n的取值范围是0-255,一般情况下,0表示正常退出,非零表示异常退出.如果状态码是0-255之外的数值,则会被强制转换为uint8_t类型的数值,比如-1会被转换为255,256会发生类型宽度截断,被转换为0.状态码n可以不指定,默认是上一条命令的退出状态码. 关于状态码值的定义尚未有统一的标准,但是结束程序时随意的指定一个状态码是一个不好的行为,应该使用

  • linux shell之控制台打印各种颜色字体和背景的实现方法

    1 问题 控制台打印各种颜色字体和背景 字体颜色 #30:黑 #31:红 #32:绿 #33:黄 #34:蓝色 #35:紫色 #36:深绿 #37:白色 背景颜色 #40:黑 #41:深红 #42:绿 #43:黄色 #44:蓝色 #45:紫色 #46:深绿 #47:白色 echo -e "\e[43;35m chenyu\e[0m hello word" 比如上面的命令,43是背景颜色,35是字体颜色, \e[0m 是还原本色 2 代码实现 这里写的是color.sh文件如下 #!/b

  • shell脚本实现监控某个进程意外停止后拉起进程

    要监护的进程启动脚本:实现脚本写入crontab定时任务 #!/usr/bin/env bash # scheduled task at 22:00 everyday script_path=`eval pwd` user_name=`whoami` echo "crontab_script_path:${script_path}" sudo echo "* * * * * cd ${script_path} && sh xxx.sh > start_c

  • linux shell之通过标识测试文件系统属性的方法示例

    1 通过标识测试文件系统属性 [ -f $file_var ] :如果给定的变量包含正常的文件路径或文件名,则返回真. [ -x $var ] :如果给定的变量包含的文件可执行,则返回真. [ -d $var ] :如果给定的变量包含的是目录,则返回真. [ -e $var ] :如果给定的变量包含的文件存在,则返回真. [ -c $var ] :如果给定的变量包含的是一个字符设备文件的路径,则返回真. [ -b $var ] :如果给定的变量包含的是一个块设备文件的路径,则返回真. [ -w

  • linux shell中if的各种判断

    shell编程中使用到得if语句内判断参数 –b当file存在并且是块文件时返回真 -c当file存在并且是字符文件时返回真 -d当pathname存在并且是一个目录时返回真 -e当pathname指定的文件或目录存在时返回真 -f当file存在并且是正规文件时返回真 -g当由pathname指定的文件或目录存在并且设置了SGID位时返回为真 -h当file存在并且是符号链接文件时返回真,该选项在一些老系统上无效 -k当由pathname指定的文件或目录存在并且设置了"粘滞"位时返回真

  • 干掉一堆mysql数据库,仅需这样一个shell脚本(推荐)

    一大早就被电话吵醒了,云某项目数据库全挂了,启动不了(睡得太死,没听到报警短信),吓得不轻啊! 电话中说所有mysql数据库主库都启动不了,但从库正常,怀疑是主库去连其它阿里云的主库了.这些数据库,以前是从阿里云迁移到idc机房的,因此他有这个判断. 赶紧打开电脑,连***,登录其中一个数据库服务器,试着执行如下命令启动mysql服务 [root@bbsmysql121 backup]#mysqld_safe –user=mysql & 启动失败,又换一台数据库服务器尝试,还是失败.考虑到所有的

  • 使用shell脚本每天对MySQL多个数据库自动备份的讲解

    Linux下使用shell脚本,结合crontab,定时备份MySQL下多个数据库,每次备份的数据存放于以日期命名的文件夹中,同时删除超过设定的备份保留时间的数据. 以下例子设定备份保留时间为1个月(-1month),可根据需求修改 #! /bin/bash # MySQL用户 user="root" # MySQL密码 userPWD="123456" # 需要定时备份的数据表列表 dbNames=(db_test1 db_test2 db_test3 db_te

随机推荐