0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

通过一个脚本搞懂fork、source和exec

阿铭linux 来源:阿铭linux 2023-02-03 16:05 次阅读

前言

这是一个经常在面试时被问到的一个问题,对于刚刚接触shell的初学者来说,确实不太好搞明白这三者的区别,下面我通过两个脚本来帮助你理解它们。

前置知识点

1)我们所执行的任何程序,都是由父进程(parent process)所产生出来的一个子进程(child process),子进程在结束后,将返回到父进程去。此现像在Linux系统中被称为fork。当子进程被产生的时候,将会从父进程那里获得一定的资源分配、以及继承父进程的环境( 如环境变量)。

2)环境变量大体可以分为三类:

  • 内置变量:系统提供,不用定义,不能修改,比如$#,$?,$*,$0等
  • 环境变量:系统提供,不用定义,可以修改,当前进程及其子进程中使用,比如PATH,PWD,SHELL等
  • 用户变量(本地变量):用户定义,可以修改,在当前进程使用,比如var=123等

3)环境变量只能从父进程到子进程单向继承。换句话说:在子进程中的环境如何变更,均不会影响父进程的环境。

4)先准备两个示例脚本:

vi 1.sh ##内容如下

#!/bin/bash
A=aminglinux
echo "PID for 1.sh before exec/source/fork:$$"
export A
echo "1.sh: $A is $A"


case $1 in
    fork)
        echo "using fork"
        bash 2.sh
        ;;
    source)
        echo "using source"
        source 2.sh
        ;;
    exec)
        echo "using exec"
        exec ./2.sh
        ;;
    *)
        echo "using fork"
        bash 2.sh
        ;;
esac


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

vi 2.sh ##内容如下

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

给两个脚本执行权限

chmod +x 1.sh 2.sh

Fork

Fork,字面上就是派生的意思,在当前shell中(可以是脚本,也可以是命令行终端)去执行一个bash命令,那么就会派生一个sub-shell,也就是所谓的子shell。这个过程就是fork。bbd720bc-a398-11ed-bfe3-dac502259ad0.pngFork模式下,子shell会继承父shell的环境变量、用户变量,当子shell结束时,子shell里面产生的环境变量并不会带到父shell中。通过执行示例脚本,来验证上面的结论:
bash 1.sh fork

bbe4dc84-a398-11ed-bfe3-dac502259ad0.png

1)1.sh的PID为15242也就是父shell的PID,而2.sh的PID为15243,这个是子shell的PID。2)在1.sh里定义了变量A,值为aminglinux,然后fork了一个子shell去执行了2.sh,在2.sh里变量A的值是ops,但是当2.sh执行完后,再回到1.sh,变量A的值依然是aminglinux。

Source

Source模式下,子shell执行时获取的环境变量会会影响到父shell。与fork的区别在于,不会额外打开一个sub-shell来执行被调用的脚本,而是在同一个shell中执行。所以,被调用的脚本中声明的变量和环境变量, 都可以在主脚本中得到和使用。

下面来执行下示例脚本:

bash 1.sh source

bbff84e4-a398-11ed-bfe3-dac502259ad0.png

1)无论1.sh还是2.sh,PID都是17164,这说明source并不会开启sub-shell,而是和父shell使用了同一个进程。

2)source 2.sh后,变量A的值变成了ops,而后也被带到了1.sh里。

Exec

Exec模式下,一旦执行了子shell,就不会再去执行父shell了。它与fork不同,不需要新开一个sub-shell来执行被调用的脚本,被调用的脚本与父shell在同一个shell内执行,这个特性和source一样。但是使用exec调用一个新脚本后, 父shell中exec之后的内容就不会再执行了。

我们来看示例脚本执行结果:

bash 1.sh exec

bc0eb0fe-a398-11ed-bfe3-dac502259ad0.png

1)1.sh和2.sh的PID都是18633,这说明exec和source一样,并不会开启sub-shell,而是和父shell使用了同一个进程。

2)exec调用完2.sh之后,脚本就结束了,没有再继续,这是exec的特性!

总结

  • source命令: 不创建子进程,在当前Shell进程中执行脚本,会将新的环境变量传递到当前shell来。
  • exec命令: 不创建子进程, 在当前Shell进程中执行脚本,父脚本中exec行之后的内容不会执行。
  • fork属于系统调用, 会创建一个子进程, 父进程会阻塞等待子进程执行结束, 然后继续往下执行,子进程里的环境变量不影响父进程。

审核编辑 :李倩


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 变量
    +关注

    关注

    0

    文章

    613

    浏览量

    28364
  • Shell
    +关注

    关注

    1

    文章

    365

    浏览量

    23362
  • 脚本
    +关注

    关注

    1

    文章

    389

    浏览量

    14862

原文标题:通过一个脚本搞懂fork、source和exec

文章出处:【微信号:aming_linux,微信公众号:阿铭linux】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    关于 forkexec 是如何在 Unix 上工作的

    本文是关于 forkexec 是如何在 Unix 上工作的。你或许已经知道,也有人还不知道。几年前当我了解到这些时,我惊叹不已。
    的头像 发表于 01-22 09:09 5032次阅读

    Linux下多进程编程之exec函数语法及使用实例

    自己重生。● 如果进程想执行另一个程序,那么它就可以调用fork()函数新建进程,然后调
    发表于 08-14 10:09

    【Linux学习杂谈】之exec族函数

    )fork创建的子进程是为了单独地执行新程序宏观上面是父子进程同时进行的。(2)可以利用fork的返回值通过if判断在当中直接书写我们的父子进程的内容,但是这样有
    发表于 09-08 13:14

    使用fork/exec/wait/exit等函数去创建进程

    运行。本期课程首先将会带领大家了解什么是进程,通过编程,学习使用fork/exec/wait/exit等函数去创建进程、管理控制
    发表于 11-04 08:58

    最常见的fork用法是什么

    的进程一模一样,这两 进程都会继续运行最常见的fork用法是创建新的进程,然后使用exec
    发表于 12-15 07:38

    Linux系统的fork运行机制分析

    如果其中进程的输出结果是“pid1:1001, pid2:1002”,写出其他进程的输出结果(不考虑进程执行顺序)。 明显这道题的目的是考察linux下fork的执行机制。下面我们通过
    发表于 04-26 16:26 1164次阅读
    Linux系统的<b class='flag-5'>fork</b>运行机制分析

    对“Fork”做一个技术方面的简介

    )。随着 GitHub 的流行,我们经常能在各种文章中见到,“fork 某某项目”等说法,是的,“fork”这个直没有正式的译名。其实
    发表于 04-02 14:48 307次阅读

    最为精简的Linux Fork炸弹解析

    转自:http://blog.saymagic.cn/2015/03/25/fork-bomb.html Jaromil在2002年设计了最为精简的Linux Fork**
    的头像 发表于 09-07 16:12 1128次阅读

    SystemVerilog中的fork-join_any

    fork-join_any和fork-join有所不同,fork-join_any的父进程直阻塞,直到任何
    的头像 发表于 12-09 09:05 2123次阅读

    Qt中的三exec之间有什么联系

    在Qt中,常见到三exec,第一个是QApplication::exec(),第二是QEventLoop::
    的头像 发表于 03-06 09:44 2411次阅读

    分享249拿来即用的shell脚本

      由于脚本案例太多,在此仅展示部分,完整版领取方式请见文末       249拿来即用的shell脚本!   这249Shell脚本
    的头像 发表于 07-07 10:52 1180次阅读
    分享249<b class='flag-5'>个</b>拿来即用的shell<b class='flag-5'>脚本</b>

    为什么shell脚本中执行命令要加exec?这个exec有什么作用呢?

    正常情况下,如果我们想要在shell脚本中执行命令,我们只用将该命令原样写到这个shell脚本中就好了。
    的头像 发表于 08-21 09:10 3114次阅读
    为什么shell<b class='flag-5'>脚本</b>中执行命令要加<b class='flag-5'>exec</b>?这个<b class='flag-5'>exec</b>有什么作用呢?

    编写点名器脚本

    目的:编写脚本,可以将准别好的名字合集的.txt传入脚本,然后每次随机显示一个人的姓名
    的头像 发表于 11-06 12:41 593次阅读
    编写<b class='flag-5'>一</b><b class='flag-5'>个</b>点名器<b class='flag-5'>脚本</b>

    linux中source命令的用法

    在Linux中,source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。source命令可以用于读取并执行脚本文件中的命令,通常用于在当前shell环境中重新加载
    的头像 发表于 11-08 14:35 2329次阅读

    docker exec命令的使用方法

    Docker是种开源的容器化平台,可以让开发人员在容器中打包和运行应用程序。它提供了种快速、可靠和致的方式来构建、部署和运行应用程序。Docker exec命令是Docker提供
    的头像 发表于 11-23 09:33 1620次阅读