Shell中调用外部脚本的若干种方式

在运行shell脚本时候,有三种方式来调用外部的脚本,exec(exec script.sh)方式、source(source script.sh)方式、fork(./script.sh)方式。

fork方式

通常情况下在系统中通过相对路径或绝对路径执行一个命令时,都会由父进程开启一个子进程,当子进程结束后再返回父进程,这种行为过程就叫fork。当脚本中正常调用一个外部命令或其他脚本时,都会fork一个子shell进程,我们的命令会运行在这个子shell中。

subshell.sh

#!/bin/bash

#使用&在后台进程开启子shell

count=0

for i in {1..254}
do
  ping -c1 -i0.2 -WL 192.168.43.$i >/dev/null && let count++ &
done

echo $count

for_test.sh

#!/bin/bash

sleep 5

#绝对路径或相对路径调用外部脚本时会fork子进程
/home/minger/share/shell/subshell.sh

这个脚本在执行的过程中会打开一个终端窗口,反复执行pstree可以获得如下的进程树信息。可以看出,我们脚本调用一个外部命令时(sleep)时,系统会fork一个子shell,sleep命令是在子shell中执行的。

当脚本通过相对路径或者绝对路径调用外部其他脚本时,会fork一个子进程,并且subshell.sh脚本中命令被触发执行时也会再次fork子进程。

可以用pstree查看:

在这里插入图片描述

在这里插入图片描述
使用fork方式开启的子进程是父进程的一个副本,因此会自动单向继承父进程的环境,如环境变量、资源权限、内存中的数据、信号等等。但是,父进程无法继承子进程环境。

exec方式

使用exec方式调用其他命令或脚本时,系统不会开启子进程,而是使用新的程序替换当前的shell环境,因为当前shell被替换了,所以当exec调用的程序结束后,当前环境会被关闭。

exec执行命令流程图:
在这里插入图片描述
上面的图中,通过exec时执行ls命令,一个是使用用echo命令让屏幕回显一个字符串信息,最后一个是cd 命令,用于切换目录。但是,第一命令使用exec调用ls,系统使用ls命令替换当前的脚本,整个进程就变成了一个ls命令,当ls命令结束后进程也就结束了。

下面来看看例子:

#!/bin/bash

exec ls
echo "test"

cd /shell

在这里插入图片描述

这里有个特例,当exec后面的参数文件重定向时,不会替换当前的shell环境,脚本后续其他命令也不会受到任何影响。

source方式

使用source或者“.”来调用外部脚本,不会产生新的进程,继承当前shell环境变量,而且被调用的脚本运行结束后,它拥有的环境变量和声明变量会被当前shell保留,类似将调用脚本的内容复制过来直接执行。执行完毕后原主shell继续运行。

下面来看个简单例子:

tmp.sh

#!/bin/bash

env="Minger"

source.sh

#!/bin/bash

source /tmp/tmp.sh

echo "hi,$env"

ls /

在这里插入图片描述

在上面的source.sh脚本中使用source命令加载/tmp/tmp.sh脚本,source命令会在不开启shell情况下,将tmp.sh中的所有命令加载当前shell环境中,类似tmp.sh文件中的所有命令编写在source.sh文件中的一样。

在这里插入图片描述
欢迎关注公众号【程序猿编码】,添加本人微信号(17865354792),回复:领取学习资料。或者回复:进入技术交流群。网盘资料有如下:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值