zoukankan      html  css  js  c++  java
  • Shell:子shell概念

    Blog:博客园 个人

    shell环境

    每个shell进程有一个自己的运行环境,不同的Shell进程有不同的Shell环境。Shell解析命令行、调用命令行的过程都在这个环境中完成。

    调用shell程序时,会读取配置文件来初始化Shell环境。

    读取配置文件情况分为两种:

    • 用户登录启动的shell

    image-20200722201723821

    • 非用户登录启动的shell

    image-20200722202245669

    什么是子shell

    所谓子shell,即从当前shell环境中新开了一个shell环境,这个新开的shell环境就是子shell,而开启子shell的环境称为该子shell的父shell。

    子Shell的本质可以理解为Shell的子进程,子进程的概念是由父进程的概念引申而来的,在Linux系统中,系统运行的应用程序几乎都是从init(pid为1的进程)进程派生而来的,所有这些应用程序都可以视为init进程的子进程,而init则为它们的父进程。通过执行pstree -a命令就可以看到init及系统中其他进程的进程树信息:

    [root@test ~]# pstree -a
    systemd --switched-root --system --deserialize 22
      ├─NetworkManager --no-daemon
      │   └─2*[{NetworkManager}]
      ├─VGAuthService -s
      ├─agetty --noclear tty1 linux
      ├─auditd
      │   └─{auditd}
      ├─chronyd
      ├─crond -n
      ├─dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
      ├─irqbalance --foreground
      ├─lvmetad -f
      ├─master -w
      │   ├─pickup -l -t unix -u
      │   └─qmgr -l -t unix -u
      ├─polkitd --no-debug
      │   └─6*[{polkitd}]
      ├─rsyslogd -n
      │   └─2*[{rsyslogd}]
      ├─sshd -D
      │   └─sshd
      │       └─bash
      │           └─pstree -a
      ├─systemd-journal
      ├─systemd-logind
      ├─systemd-udevd
      ├─tuned -Es /usr/sbin/tuned -l -P
      │   └─4*[{tuned}]
      └─vmtoolsd
          └─2*[{vmtoolsd}]
    

    Tips:若无pstree命令,请执行yum -y install psmisc安装。

    对于Shell的子进程来说,它是一个从父级Shell进程派生而来的新的Shell进程,我们将这种新的Shell进程称为这个父级Shell的子Shell

    Shell脚本是从上至下、从左至右依次执行每一行的命令及语句的,即执行完一个命令之后再执行下一个。如果在Shell脚本中遇到子脚本(即脚本嵌套),就会先执行子脚本的内容,完成后再返回父脚本继续执行父脚本内后续的命令及语句。

    子shell会从父shell中继承很多环境,如变量、命令全路径、文件描述符、当前工作目录、陷阱等等,但子shell有很多种类型,不同类型的子shell继承的环境不相同。可以使用$BASH_SUBSHELL变量来查看从当前进程开始的子shell层数,$BASHPID查看当前所处BASH的PID,这不同于特殊变量$$值,因为$$在大多数情况下都会从父shell中继承。

    注意:子 Shell 虽然能使用父 Shell 的的一切,但是如果子 Shell 对数据做了修改,比如修改了全局变量,那么这种修改只能停留在子 Shell,无法传递给父 Shell。不管是子进程还是子 Shell,都是“传子不传父”。

    子shell的分类

    大致分为两类:

    • sub shell:通过进程替换<(cmd),>(cmd)、命令替换$(cmd)(cmd)|或者$隐式生成的子shell。因为父shell是通过fork创建sub shell,因此子shell会从父shell中继承很多环境,如变量、命令全路径、文件描述符、当前工作目录、陷阱等等;
    • child shell:通过以可执行文件的方式运行shell脚本或直接在当前shell中启动shell解释器的方式得到的子shell。父shell通过fork-exec的方式创建子shell,导致父shell和子shell除了维持“父子关系”外,没有其他关联。

    注释:使用 fork() 函数可以创建一个子进程;除了 PID(进程ID)等极少的参数不同外,子进程的一切都来自父进程,包括代码、数据、堆栈、打开的文件等,就连代码的执行位置(状态)都是一样的。

  • 相关阅读:
    Github精选——devops一体化监控平台工具WGCLOUD
    [搬运][中英双语]字体推荐 | 如果你每天都在代码面前,为何不让其变得有趣起来呢?
    【学习笔记】二分图最大匹配 -- 从网络流到匈牙利算法
    【详细揭秘】多重集の交错排列
    支配树口胡
    题解 洛谷 P2388 阶乘之乘
    [eJOI2019]异或橙子 题解
    VBA (Excel) 插入多行的方法 & 算法对比
    20000套免费ppt模板获取攻略
    包你扫到敬业福,集五福活动,福字大全
  • 原文地址:https://www.cnblogs.com/Rohn/p/14111943.html
Copyright © 2011-2022 走看看