![如何控制后台子shell?](https://linux22.com/image/78648/%E5%A6%82%E4%BD%95%E6%8E%A7%E5%88%B6%E5%90%8E%E5%8F%B0%E5%AD%90shell%EF%BC%9F.png)
如果我在 bash 提示符下运行以下命令:
(for i in {1..100}; do echo $i; sleep 1; done) &
它将开始计数并立即返回到我的提示。我可以继续正常工作,但每一秒它都会在我正在处理的内容之上打印一个新数字。我可以按预期看到工作jobs
和fg
/它。kill
现在,如果我将此命令移动到以下脚本中test.sh
:
#!/usr/bin/bash
(for i in {1..100}; do echo $i; sleep 1; done) &
当我跑步时./test.sh
,同样的事情发生了——但工作不再出现jobs
,我也不能fg
再做。究竟为什么第二个行为与第一个行为如此不同,以及如何控制第二个作业(不找到 PID 并以这种方式杀死它)?
答案1
你必须跟踪它的 PID,这是$!
为你设置的,就是为了这个目的。例如,
#!/usr/bin/bash
(sleep 30; echo "slept for 30 seconds") &
sleeping_pid=$!
# do something
kill $sleeping_pid # or you can wait on it, or...
请注意,这$!
是最近启动的后台作业。所以它确实容易被覆盖,这就是为什么我立即将其复制到另一个变量中。
答案2
在我的特定情况下,我能够通过将其中的子 shell 更改test.sh
为组命令来实现我的目标。
(for i in {1..100}; do echo $i; sleep 1; done) &
成为
{ for i in {1..100}; do echo $i; sleep 1; done; } &
然后我就可以使用所有的作业控制功能了。幸运的是,对于我的目的而言,子 shell 和组命令基本上是等效的,但它们可能并不适合所有人。