Shell:子shell概念

Blog:博客园 我的linux

shell环境

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

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

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

  • 用户登陆启动的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安装。debug

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

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

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

注意:子 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)等极少的参数不一样外,子进程的一切都来自父进程,包括代码、数据、堆栈、打开的文件等,就连代码的执行位置(状态)都是同样的。

相关文章
相关标签/搜索