• 013-在 Shell 脚本中调用另一个 Shell 脚本的三种方式


    如下:

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

    1、fork

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

    2、exec

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

    3、source

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

    测试

    脚本1、父脚本

    #!/usr/bin/env bash
    
    A=1
    
    echo "执行调用之前进程Id exec/source/fork: PID for 1.sh = $$"
    
    export A
    echo "In 1.sh: variable A=$A"
    
    case $1 in
            --exec)
                    echo -e "==> using exec…
    "
                    exec ./2.sh ;;
            --source)
                    echo -e "==> using source…
    "
                    . ./2.sh ;;
            *)
                    echo -e "==> using fork by default…
    "
                    ./2.sh ;;
    esac
    
    echo "执行调用之后进程Id exec/source/fork: PID for 1.sh = $$"
    echo -e "父脚本1.sh: variable A=$A
    "

    脚本2、子脚本

    #!/usr/bin/env bash
    
    echo "子脚本2PID for 2.sh = $$"
    echo "In 2.sh get variable A=$A from 1.sh"
    
    A=2
    export A
    
    echo -e "子脚本2.sh默认A=2: variable A=$A
    "

    测试一、fork方式,直接调用

    $ ./1.sh
    执行调用之前进程Id exec/source/fork: PID for 1.sh = 71145
    In 1.sh: variable A=1
    ==> using fork by default…
    
    子脚本2PID for 2.sh = 71146
    In 2.sh get variable A=1 from 1.sh
    子脚本2.sh默认A=2: variable A=2
    
    执行调用之后进程Id exec/source/fork: PID for 1.sh = 71145
    In 1.sh: variable A=1

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

    测试二、exec方式:./1.sh exec

    $ ./1.sh exec
    执行调用之前进程Id exec/source/fork: PID for 1.sh = 71288
    In 1.sh: variable A=1
    ==> using exec…
    
    子脚本2PID for 2.sh = 71288
    In 2.sh get variable A=1 from 1.sh
    子脚本2.sh默认A=2: variable A=2

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

    测试三、source方式:./1.sh source

    $ ./1.sh source
    执行调用之前进程Id exec/source/fork: PID for 1.sh = 71319
    In 1.sh: variable A=1
    ==> using source…
    
    子脚本2PID for 2.sh = 71319
    In 2.sh get variable A=1 from 1.sh
    子脚本2.sh默认A=2: variable A=2
    
    执行调用之后进程Id exec/source/fork: PID for 1.sh = 71319
    父脚本1.sh: variable A=2

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

    对比

    Command进程变量Explanation
    fork 父子不同进程 子继承父变量,子不能传递给父

    新开一个子 Shell 执行,当子进程执行完毕后会返回父进程,但是父进程的环境变量不会因子进程的改变而改变。

    子 Shell 可以从父 Shell 继承环境变量,但是子 Shell 中的环境变量不会带回给父 Shell。

    exec 同进程 子继承父,子进程结束 在同一个 Shell 内执行,但是父脚本中 exec 行之后的内容就不会再执行了,相当于父脚本执行exec进入子脚本后不再回到父脚本。
    source 同进程 子继承父变量,子同时回传给父 在同一个 Shell 中执行,在被调用的脚本中声明的变量和环境变量, 都可以在主脚本中进行获取和使用,相当于合并两个脚本在执行。

     脚本地址:https://github.com/bjlhx15/shell.git 下的test/invokesh

  • 相关阅读:
    预备作业03
    预备作业02
    预备作业01
    20162319莫礼钟 2016-2017-2 《程序设计与数据结构》第1周学习总结
    预备作业03
    20162319 莫礼钟 预备作业02
    20162319莫礼钟 预备作业01
    20162307 实验一 实验报告
    20162307 第4周学习总结
    20162307 第3周学习总结
  • 原文地址:https://www.cnblogs.com/bjlhx/p/11921311.html
Copyright © 2020-2023  润新知