为什么shell会在这种情况下启动另一个shell进程?

时间:2015-06-12 04:44:11

标签: linux bash shell

这是代码

#!/bin/bash
echo $$
cd $HOME && sleep 10 &
exit 0

现在让我们运行sh test.sh

我得到了结果: 21936这是我运行的shell进程的pid。

如果我在 10秒内执行ps -ef | grep test.sh ,那就是睡眠时间。

我得到了root 21937 1 0 12:41 pts/0 00:00:00 sh test.sh

Q1:它应该是test.sh而不是sleep进程。为什么还有test.sh

Q2:看起来我{gre}的test.sh与我在终端中运行的test.sh不一样,取决于PID。那么新的test.sh是如何出来的?

嗨,如果我改变了

,还有另一种情况
cd $HOME && sleep 10 &

cd $HOME; sleep 10 &

它的行为方式不同,test.sh会在执行sh test.sh后立即消失,只有sleep个进程。

2 个答案:

答案 0 :(得分:2)

(好吧,我会走出困境,将我的猜测/评论转化为答案。)

由于&& - 运算符本质上是一个shell内置函数,即它需要由shell处理,因此将它与&一起使用将为/ a shell创建一个子进程而不是它的各个部分(或者只是它看起来的最后部分,你预期的那样)。

当与&&链接的所有命令都是外部命令时,甚至会发生这种情况。例如,sleep 3 && sleep 5 &也将创建子shell进程。

;只是将各个命令分开,就好像它们是在不同的行上写的一样。因此,在这种情况下,只有&之前的命令被分叉("发送到后台")。

(当然,分叉的原始进程总是shell - 这就是fork的工作方式 - 但在第二种情况下,它被替换为实际命令的可执行文件sleep in你的例子。)

答案 1 :(得分:1)

来自Bash Reference Manual

  

如果命令被控制操作符&终止,则shell在子shell中异步执行命令。

也就是说,父shell进程是分叉的(在生成子shell时)。

您可以使用以下代码段轻松测试:

#!/usr/bin/env bash
print_subshell_level () { echo $BASH_SUBSHELL; }

printf "foreground: "
print_subshell_level

printf "background: "
print_subshell_level &

输出:

foreground: 0
background: 1