[笔记] shell 究竟是如何执行脚本的?
时间:2008-02-27 来源:ailms
如果是 shell 的内建命令,例如 cd 则直接在当前 shell 下执行。
否则参考下面 :
这和脚本的方式有关,一种是直接在当前 shell 下执行(例如 . , source),
另外一种是先创建一个子shell 再执行其中的二进制命令
我们先看第2种,第一种在后面会讲到。
[bob@mail ~]$ cat my.sh
#!/bin/bash
while true; do
sleep 20
done
[bob@mail ~]$
[bob@mail ~]$ ./my.sh
(无限循环)
这时在另外一个终端执行 :
[bob@mail ~]$ ps -t pts/1
PID TTY TIME CMD
17363 pts/1 00:00:00 bash
17935 pts/1 00:00:00 my.sh
17972 pts/1 00:00:00 sleep
[bob@mail ~]$
[bob@mail ~]$ ps -l 17972
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 500 17972 17935 0 76 0 - 1079 - pts/1 0:00 sleep 20
[bob@mail ~]$ ps -l 17935
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 500 17935 17363 0 76 0 - 1101 wait pts/1 0:00 /bin/bash ./my.sh
[bob@mail ~]$ ps -l 17363
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 500 17363 17362 0 75 0 - 1279 wait pts/1 0:00 -bash
[bob@mail ~]$
所以关系是 ;
(17363)-bash # 注释 ;这个就是我们登录后启动的 shell ,也就是 login shell
|----- (17935) /bin/bash ./my.sh # 注释 :这个 shell 是一个 non-interactive shell ,它带一个参数,也就是脚本路径
| ---(17972) sleep 20 # 注释 :而 17935 这个 subshell当前执行一个命令 :sleep 20 (17972)
可以看到第一个 bash (17363)并不是直接执行 sleep 20 的,而是通过一个 subshell 来执行的。
那第2个 shell (17935)又是如何执行 sleep 命令的呢?
-)1、检查 sleep ,不是 builtin 命令,则在 PATH 中找到它。
-)2、这时 17935 这个 subshell 会 fork 出一个子 shell ,我们称之为 sub-subshell ,同时 17935 调用 wait 进入等待状态
-)3、sub-subshell 发现 sleep 是一个二进制命令,则调用 exec <sleep 20> ,把 sleep 的代码装入内存,替换掉 sub-subshell 的代码
-)4、sleep 命令执行完毕(20秒过了),调用 exit 调用
-)5、sleep 的父进程 (也就是 17935)会被唤醒,并结束自己
-)6、返回 shell 提示符下