bash 中 $(cmd1|cmd2)会在当前进程下创建子进程?
问题发现
这几天写shell脚本时,发现$(cmd1|cmd2)会创建子进程
脚本如下:
#!/bin/bash
echo -e '\n\033[32;1m-----------\033[0m'
echo "The name of this file is $(basename $0)."
echo "The pid of this program is $$."
echo -e '\n\033[32;1m---- 0 ----\033[0m'
echo -e '\033[33;1mCMD: ps -ef|grep "aaaa.sh"|grep -v grep\033[0m'
ps -ef|grep "aaaa.sh"|grep -v grep
echo -e '\n\033[32;1m---- 1 ----\033[0m'
echo -e '\033[33;1mCMD: ps -ef|grep "aaaa.sh"|grep -v "bbbb"|grep -v grep\033[0m'
ps -ef|grep "aaaa.sh"|grep -v "bbbb"|grep -v grep
echo -e '\n\033[32;1m---- 2 ----\033[0m'
echo -e '\033[33;1mCMD: pgrep -a "aaaa.sh"|grep -v "bbbb"\033[0m'
pgrep -a "aaaa.sh"|grep -v "bbbb"
echo -e '\n\033[32;1m---- 3 ----\033[0m'
echo -e '\033[33;1mCMD: pgrep -a "aaaa.sh"|grep -v "$$"\033[0m'
pgrep -a "aaaa.sh"|grep -v "$$"
echo -e '\n\033[32;1m---- 4 ----\033[0m'
echo -e '\033[33;1mCMD: output=$(ps -ef|grep "aaaa.sh"|grep -v "bbbb"|grep -v grep)\033[0m'
output=$(ps -ef|grep "aaaa.sh"|grep -v "bbbb"|grep -v grep)
echo -e "$output"
echo -e '\n\033[32;1m---- 5 ----\033[0m'
echo -e '\033[33;1mCMD: output=$(ps -ef|grep "aaaa.sh"|grep -v "$$"|grep -v grep)\033[0m'
output=$(ps -ef|grep "aaaa.sh"|grep -v "$$"|grep -v grep)
echo -e "$output"
echo -e '\n\033[32;1m---- 6 ----\033[0m'
echo -e '\033[33;1mCMD: output=$(pgrep -a "aaaa.sh"|grep -v "bbbb")\033[0m'
output=$(pgrep -a "aaaa.sh"|grep -v "bbbb")
echo -e "$output"
echo -e '\n\033[32;1m---- 7 ----\033[0m'
echo -e '\033[33;1mCMD: output=$(pgrep -a "aaaa.sh"|grep -v "$$")\033[0m'
output=$(pgrep -a "aaaa.sh"|grep -v "$$")
echo -e "$output"
echo -e '\n\033[32;1m---- 8 ----\033[0m'
echo -e '\033[33;1mCMD: output=$(pgrep -a "aaaa.sh")\033[0m'
output=$(pgrep -a "aaaa.sh")
echo -e "$output"
echo -e '\n\033[32;1m-----------\033[0m'
输出结果
疑问
其中的 4、5、6、7项都输出了两个进程,请问这是shell自身的机制吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
得理解bash解释执行脚本的机制,当执行
./aaaa.sh
的初始,就已经fork()了一个子进程,这个子进程的父进程是当前登录shell随着脚本内容的被执行,根据每行命令的不同,又有不同的执行方式:
echo
命令属于bash内置命令,它在执行时相当于执行bash内部的一个函数,不创建子进程。grep
,ps
等属于外部命令(不是bash本身内部实现的命令),它们在执行时需要经过fork()
和execve()
,都需要创建子进程。而bash对管道
|
又有特殊处理,处于管道两侧的命令,会分别运行于两个子shell(每个子shell都属于原父shell的子进程),不过前一个命令的标准输出会连接到后一个命令的标准输入。