shell subprocess子进程
原文链接: shell subprocess子进程
子进程执行
- 通过 . 和 source 命令执行的脚本 会在当前的shell进程中执行,继承当前的环境变量
- 通过 sh 和 ./run.sh 执行的脚本 会新建shell进程,只有export的变量才会引用
echo 'echo $a'>run.shbash a=100 . run.sh ## 输出100 sh run.sh ## 输出空
### 后台进程执行
最近在做一线的工作,要写一个脚本 实现一些功能,发现shell的基础知识有点薄弱,借机会恶补了一下。目录结构如下,
ubuntu@ip-172-31-37-254:~/hepwd/home/ubuntu/heubuntu@ip−172−31−37−254: /hepwd/home/ubuntu/heubuntu@ip−172−31−37−254: /he ls
Dockerfile run.sh test.sh
./test.sh & or source ./test.sh &
Excute “ps -ef” in container,then
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 03:48 ? 00:00:00 /bin/bash /run.sh
root 5 1 0 03:48 ? 00:00:00 /bin/bash /run.sh
root 9 0 0 03:48 ? 00:00:00 bash
root 806 5 0 05:48 ? 00:00:00 sleep 100
root 816 0 2 05:49 ? 00:00:00 bash
root 824 1 0 05:49 ? 00:00:00 sleep 10
root 825 816 0 05:50 ? 00:00:00 ps -ef
说明: & 代表后台新启动一个子进程Pid=5,执行
然后在test.sh中 又产生一个子进程 pid=806 执行 sleep 100
最后 回到run.sh中,进程1 继续后续循环,产生一个子进程pid=824 执行sleep 10
Way 2,
source ./test.sh or . ./test.sh
Excute “ps -ef” in container,then
root@90091c73f239:/# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 06:29 ? 00:00:00 /bin/bash /run.sh
root 5 1 0 06:29 ? 00:00:00 sleep 100
root 6 0 4 06:30 ? 00:00:00 bash
root 14 6 0 06:30 ? 00:00:00 ps -ef
说明:由于test.sh 没有后台执行,中有死循环,所以该指令没有新产生子进程,并且不退出,
run.sh中的后续指令比如“sleep 10” 没有被执行。
Way 3,
exec nohup ./test.sh &
Excute “ps -ef” in container,then
root@62e826443205:/# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 1 06:43 ? 00:00:00 /bin/bash /run.sh
root 5 1 0 06:43 ? 00:00:00 /bin/bash ./test.sh
root 7 5 0 06:43 ? 00:00:00 sleep 100
root 8 1 0 06:43 ? 00:00:00 sleep 10
root 9 0 9 06:43 ? 00:00:00 bash
root 17 9 0 06:43 ? 00:00:00 ps -ef
说明:
& 后台运行子进程,产生pid=5
pid=5 产生子进程 pid=7 sleep 100
有子进程在运行,即使子进程中有死循环,也不会影响主进程的后续执行。
Way 5,
exec nohup ./test.sh
Excute “ps -ef” in container,then
root@421ddeaf1aac:/# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 06:48 ? 00:00:00 /bin/bash ./test.sh
root 5 1 0 06:48 ? 00:00:00 sleep 100
root 6 0 1 06:49 ? 00:00:00 bash
root 15 6 0 06:49 ? 00:00:00 ps -ef
说明:对比way 3 and 4,说明 exec 、nohup都不会产生新的子进程,而是在主进程中执行,
进入第一个死循环 sleep 100,所以不会继续后续代码sleep 10 的执行。
只有一个主shell在运行
Way 5,
sh ./test.sh
Excute “ps -ef” in container,then
root@7f11956d36a0:/# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 06:37 ? 00:00:00 /bin/bash /run.sh
root 5 1 0 06:37 ? 00:00:00 sh ./test.sh
root 6 5 0 06:37 ? 00:00:00 sleep 100
root 7 0 4 06:37 ? 00:00:00 bash
root 15 7 0 06:37 ? 00:00:00 ps -ef
说明: 一个脚本中 调用“sh” 执行另一个脚本,会产生子进程 pid=5
“sh test.sh” 没有后台执行,又有死循环“sleep 100”,将不退出,
故run.sh的后续指令没有被执行。
结论: & 作用 后台执行,会产生子进程
exec 、nohup 、source、.不产生子进程
sh 产生子进程 ./ 也产生子进程-并且该文件必须有可执行权限
source filename 与 sh filename 及./filename执行脚本的区别在那里呢?
1.当shell脚本具有可执行权限时,用sh filename与./filename执行脚本是没有区别得。./filename是因为当前目录没有在PATH中,所有”.”是用来表示当前目录的。
2.sh filename 重新建立一个子shell,在子shell中执行脚本里面的语句,该子shell继承父shell的环境变量,但子shell新建的、改变的变量不会被带回父shell,除非使用export。
3.source filename:这个命令其实只是简单地读取脚本里面的语句依次在当前shell里面执行,没有建立新的子shell。那么脚本里面所有新建、改变变量的语句都会保存在当前shell里面。
举例说明:
1.新建test.sh脚本,内容为:A=1
2.然后使其可执行chmod +x test.sh
3.运行sh test.sh后,echo A,显示为空,因为A=1并未传回给当前shell4.运行./test.sh后,也是一样的效果5.运行sourcetest.sh或者.test.sh,然后echoA,显示为空,因为A=1并未传回给当前shell4.运行./test.sh后,也是一样的效果5.运行sourcetest.sh或者.test.sh,然后echoA,则会显示1,说明A=1的变量在当前shell中
进程号: &产生的子进程 挂在pid=1的进程下面
sh产生的子进程 为顺序cpu 新调度产生的
杀掉子进程,父进程仍存在
---------------------
作者:马少芳
来源:CSDN
原文:https://blog.csdn.net/hubanbei2010/article/details/78623117
版权声明:本文为博主原创文章,转载请附上博文链接!