当你执行的命令:
ps -ef | grep cron
您使用
壳(...我假设的bash在你的情况下,由于grep的颜色属性,我想你正在运行一个类似于Linux发行版的gnu系统,但在其他unix/shell上也是如此......)
将执行pipe()
调用创建一个FIFO,然后它会fork()
(制作一个正在运行的副本)。这将创建一个新的子进程。这个新生成的子进程将其标准输出文件描述符(fd 1)close()
并将fd 1附加到父进程(执行该命令的shell所创建的管道的写入端)。这是可能的,因为系统调用将为每个维护有效的打开文件描述符(在这种情况下为管道fd)。这样做之后它会exec()
第一个(在你的情况下)ps
命令在你的PATH
环境变量中找到。通过调用exec()
,过程将成为您执行的命令。
所以,你现在有一个孩子的shell进程,在你的情况下,ps
命令与-ef
属性。
此时,父亲(壳)fork()
再次。这个新生成的子进程close()
是其标准输入文件描述符(fd 0),并将fd 0附加到由父进程(执行该命令的shell所创建的管道的读取侧)。
这样做会exec()
第一(你的情况)在PATH环境变量中找到grep
命令后。
现在你有两个孩子(这是兄弟),其中第一个是ps
命令-ef
属性,第二个是grep
命令和cron
属性的shell进程。管道的读取端连接到grep
命令的STDIN
,并且写入端连接到ps
命令的:ps
命令的标准输出连接到grep
命令的标准输入。
由于ps
是针对每个正在运行的进程的标准输出信息发送的,而grep是为了获得其标准输入而必须匹配给定模式的东西,所以您将得到第一个问题的答案:
- 壳运行:
ps -ef;
- 壳运行:
grep cron;
ps
发送数据(即,即使包含字符串 “的grep cron的”)以grep
grep
与STDIN
的搜索模式匹配,并且由于传递到grep
的“cron”属性匹配字符串“grep cron”:您指示grep
与“cron”字符串匹配,并且因为“grep cron”是在grep
开始执行时由ps
返回的字符串。
当你执行:
ps -ef | grep '[c]ron'
通过属性指示grep
匹配含有 “C”,其次是 “罗恩” 的东西。如同第一实施例,但在这种情况下,它会打破由ps
因为返回匹配字符串:
- 外壳运行:
ps -ef;
- 外壳运行:
rep [c]ron;
ps
发送数据(即使包含字符串grep [c]ron
)到grep
grep
与stdin的搜索模式不匹配,因为包含“c”后跟“ron”的字符串未找到,但找到包含“c”的字符串后跟“] ron”
GNU grep
没有任何字符串匹配限制,并且在某些平台上(我认为Solaris,HPUX,aix)字符串的限制是由“$ COLUMN”变量或终端的屏幕宽度给出的。
希望这个长时间的回应澄清了shell管道过程。
提示:
ps -ef | grep cron | grep -v grep
你会惊讶于睡眠的结果3 |睡3 |睡3';-) – Alfe