shell subprocess子进程


原文链接: shell subprocess子进程

子进程执行

  1. 通过 . 和 source 命令执行的脚本 会在当前的shell进程中执行,继承当前的环境变量
  2. 通过 sh 和 ./run.sh 执行的脚本 会新建shell进程,只有export的变量才会引用
    echo 'echo $a'>run.sh
    bash 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
    版权声明:本文为博主原创文章,转载请附上博文链接!
`