您的位置:首页 > 运维架构 > Shell

shell脚本调用方法及适用场景

2015-12-05 21:19 561 查看
/[b]*****************************[/b]

* Author : Samson

* Date : 12/05/2015

* Test platform:

* GNU bash, 4.3.11

* Debian GNU/Linux 8

* [b]***************************[/b]/

目前来说有三种方法:

    1. 脚本绝对路径

        这个方式是最普通的,底层调用的是fork实现,运行的时候开一个子shell执行调用的脚本,子shell执行的时候,父shell还在

        子shell执行完毕后返回父shell,子shell从父shell继承环境变量,但是子shell中的环境变量不会带回父shell中。

    2. 句号 + 脚本绝对路径

        底层调用的是source实现的,他于fork的区别是不新开一个子shell来执行被调用的脚本,而是在同一个shell中执行,所以被调用脚本中申明的变量和环境变量,都可以在主脚本中得到和使用。

    3. exec + 脚本绝对路径

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

下面是一个脚本的例子:

父脚本(1.sh):  

#!/bin/bash 

A=B 

echo "PID for 1.sh before exec/source/fork: $$"

export A

echo "1.sh: \$A is $A" 

case $1 in 

        exec) 

                echo "using exec…"

                exec ./2.sh ;; 

        source) 

                echo "using source…" 

                . ./2.sh ;; 

        *)

                  echo "using fork by default…" 

                ./2.sh ;; 

esac 

echo "PID for 1.sh after exec/source/fork:$$" 

echo "1.sh: \$A is $A" 

子脚本(2.sh):

#!/bin/bash
echo "PID for 2.sh: $$"
echo "2.sh get \$A=$A from 1.sh"
A=C
export A
echo "2.sh: \$A is $A"


第一种(使用绝对路径)情况的执行结果:

~/$ ./1.sh

PID for 1.sh before exec/source/fork:10124

1.sh: $A is B

using fork by default…

PID for 2.sh: 10125

2.sh get $A=B from 1.sh

2.sh: $A is C

PID for 1.sh after exec/source/fork:10124

1.sh: $A is B

第二种(source)情况的执行结果:

~/ $ ./1.sh source

PID for 1.sh before exec/source/fork:10143

1.sh: $A is B

using source…

PID for 2.sh: 10143

2.sh get $A=B from 1.sh

2.sh: $A is C

PID for 1.sh after exec/source/fork:10143

1.sh: $A is C

第三种(exec)情况的执行结果:

 ~/ $ 1.sh exec

1.sh:未找到命令

 ~/ $ ./1.sh exec

PID for 1.sh before exec/source/fork:10140

1.sh: $A is B

using exec…

PID for 2.sh: 10140

2.sh get $A=B from 1.sh

2.sh: $A is C 

三种情况分别适用的场景及优缺点:

第一种情况(绝对路径)和第三种(exec)情况,对于脚本程序本身来说必须是拥有+x(可执行)的权限的,而使用source方法对此没有要求;

exec命令本身是使程序本身替换掉当前shell程序,故使用此命令的适用场景为进行执行的脚本是一个守护进程,否则将执行完exec命令行后退出当前shell进程,这也即是上面的测试程序没有执行后面的语句的原因;在man sh中的exec参数说明中如下描述:

exec [command arg ...]

            Unless command is omitted, the shell process is replaced with the specified program (which must be a real program, not a shell builtin or function).  Any redirections on the exec  command are marked as permanent, so that they are not undone when
the exec command finishes.

第二种方法(source)适用于对多个脚本程序中的环境变量要进行共享的场景;

第一种方法(绝对路径)适用于多个脚本中的环境变量等私有的不进行共享的场景;

1995
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: