如何在bash中将两个进程运行为一个进程?

4

我有两个命令 foo 和 bar。

foo 在没有标准输入输出或标准错误输出的情况下长时间运行。bar 是 foo 的客户端,具有标准输出和标准错误输出,但没有标准输入。

我想从一个 shell 中运行它们,能够使用 ctrl-c 来同时终止它们,并且能够实时查看 bar 的输出。

例如以下顺序:

foo & bar kill -9

但不需要手动执行 kill 命令,而是在按下 ctrl-c 后自动执行。

是否有一种脚本方式可以实现这个功能?

谢谢。

2个回答

5

不要使用kill -9

你应该在EXIT上进行陷阱捕获,而不是在INT上进行。

trap 'kill $fooPid $barPid' EXIT
foo & fooPid=$!
bar & barPid=$!
wait

无论foo和bar退出的原因是什么(除非它被SIGKILL杀死),此解决方案始终确保其终止。

如果您想避免保留PID(这会有一些竞态条件问题),可以改为执行以下操作:

trap 'kill $(jobs -p)' EXIT
foo &
bar &
wait

如果您的脚本没有其他任务,那么这是一个更好(更清洁!)的解决方案。

附注: 这些解决方案意味着foobar可以写入您的终端(您的脚本的stdout),但两者都不能从stdin读取。如果您需要foobarstdin读取,则解决方案会变得稍微复杂一些。


我同意你所说的一切,除了kill -9。我以前见过这种做法,但只要你理解进程的作用,它就没问题。只要没有资源超出进程的生命周期,-9就可以使用,而且避免了(可能)混乱的分阶段杀死进程(先kill,然后如果它们拒绝死亡,则稍后再kill -9)。 - paxdiablo
@Pax:如果您知道该进程的功能并且不需要任何清理,则 SIGTERM 与 SIGKILL 完全相同,因此您可以发送 SIGTERM。而混乱的分阶段杀死确实应该尽一切可能避免;通过仅发送 SIGTERM 并增加耐心 :-) - lhunath

2

您可以设置一个bash脚本来运行程序,并使用trap来捕获CTRL-C。然后,在由trap调用的函数中,只需终止这些程序。

我已经有一段时间没有做过这个了,但我认为以下内容可以说明它。

#!/bin/bash
xx() {
    kill -9 $pid1
    kill -9 $pid2
    echo bye
}
trap 'xx' SIGINT
sleep 1000 &
pid1=$!
sleep 2000 &
pid2=$!
sleep 3600

只需运行此脚本并使用CTRL-C,您将发现它会终止两个睡眠进程。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接