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),回复:领取学习资料。或者回复:进入技术交流群。网盘资料有如下:

在这里插入图片描述

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Shell脚本是一种命令行解释器,可以直接执行命令、操作文件等。在实际应用,运行的Shell脚本往往需要传入参数来控制脚本的行为和逻辑,因此学会Shell脚本传参对于我们写出好的脚本是十分必要的。下面介绍Shell脚本传参的三种方式: 1. 位置参数传参: 通过$1、$2、$3...的变量获取传入的参数,其$0表示脚本的名字。 例如: ``` #!/bin/bash echo "The first parameter is $1 and the second parameter is $2." ``` 执行: ``` ./test.sh hello world ``` 输出: ``` The first parameter is hello and the second parameter is world. ``` 2. 特殊变量传参: Shell脚本还提供了一些特殊变量可以用来获取所传递参数的信息,如传递参数个数的${#}、所有参数组成的${*}和所有参数组成的${@}。 例如: ``` #!/bin/bash echo "There are $# parameters." echo "All parameters are ${*}." echo "All parameters are ${@}." ``` 执行: ``` ./test.sh hello world 123 ``` 输出: ``` There are 3 parameters. All parameters are hello world 123. All parameters are hello world 123. ``` 3. 命令行传参: 在执行Shell脚本时直接通过“sh test.sh 参数1 参数2…”的方式传参。这种方式需要注意空格和引号,可以使用双引号保留参数的空格。 例如: ``` #!/bin/bash echo "The first parameter is $1 and the second parameter is $2." ``` 执行: ``` sh test.sh "hello world" 123 ``` 输出: ``` The first parameter is hello world and the second parameter is 123. ``` 总结:以上三种方式Shell脚本传参的常用方法,通过具体的需求来决定选用哪种方式,以达到最好的效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值