在bash shell
中执行一个命令时,其实是由bash shell fork
出一个子进程,然后在这个子进程中运行相应的命令,直至退出。在一个终端执行下列操作:
[root@localhost ~]# echo $$
19954
[root@localhost ~]# sleep 100
在另一个终端执行下列操作:
[root@localhost bin]# ps -ef | grep 19954
root 19954 19353 0 03:01 pts/3 00:00:00 /bin/bash
root 20265 19954 0 04:39 pts/3 00:00:00 sleep 100
root 20267 19354 0 04:39 pts/0 00:00:00 grep --color=auto 19954
可以看到第一个终端的bash shell
(进程ID
是19954
)fork
产生了sleep 100
这个进程。
当在bash shell
中执行一个bash shell
脚本时,其实先会fork
出一个subshell
子进程,再由这个子进程执行脚本中的命令。举个例子可能会解释的更清楚。
这是一个简单的bash shell
脚本(test.sh
):
#!/bin/bash
sleep 100
在一个终端执行这个脚本:
[root@localhost ~]# echo $$
19954
[root@localhost ~]# ./test.sh
在另一个终端执行下列操作:
[root@localhost bin]# ps -ef | grep test
root 20309 19954 0 05:01 pts/3 00:00:00 /bin/bash ./test.sh
root 20316 19354 0 05:02 pts/0 00:00:00 grep --color=auto test
[root@localhost bin]# ps -ef | grep 20309
root 20309 19954 0 05:01 pts/3 00:00:00 /bin/bash ./test.sh
root 20310 20309 0 05:01 pts/3 00:00:00 sleep 100
root 20318 19354 0 05:02 pts/0 00:00:00 grep --color=auto 20309
可以看到第一个终端的bash shell
(进程ID
是19954
)fork
产生了test.sh
这个进程(进程ID
是20309
),而test.sh
这个进程又fork
产生了sleep 100
这个进程。
接下来要提一下source
(“.
”命令作用是一样的)这个bash shell
内建命令。man source
是这样解释的:
. filename [arguments]
source filename [arguments]
Read and execute commands from filename in the current shell environment and return the exit status of the last command executed from filename. If filename does not contain a slash, file names in PATH are used to find the directory containing filename. The file searched for in PATH need not be executable. When bash is not in posix mode, the current directory is searched if no file is found in PATH. If the sourcepath option to the shopt builtin command is turned off, the PATH is not searched. If any arguments are supplied, they become the positional parameters when filename is executed. Otherwise the positional parameters are unchanged. The return status is the status of the last command exited within the script (0 if no commands are executed), and false if filename is not found or cannot be read.
可以看出,“source filename [arguments]
”会在当前的shell
环境执行文件中的命令,也就是不会产生一个subshell
子进程。仍利用test.sh
脚本演示一下:
在一个终端执行这个脚本:
[root@localhost ~]# echo $$
19954
[root@localhost ~]# source ./test.sh
在另一个终端执行下列操作:
[root@localhost bin]# ps -ef | grep test
root 20349 19354 0 05:24 pts/0 00:00:00 grep --color=auto test
[root@localhost bin]# ps -ef | grep 19954
root 19954 19353 0 03:01 pts/3 00:00:00 /bin/bash
root 20345 19954 0 05:24 pts/3 00:00:00 sleep 100
root 20347 19354 0 05:24 pts/0 00:00:00 grep --color=auto 19954
可以看到并没有test.sh
这个进程,sleep 100
这个进程是由bash shell
(进程ID
是19954
)进程直接fork
产生的。
参考资料:
Shell十三问