我需要在短暂的容器/ VMS(远程)壳为一个测试执行引擎上运行基本上任意命令泄漏后台进程。有时这些泄漏后台进程,然后导致整个命令挂起。这可以归结为简单的命令:壳:清理该挂起由于共享标准输出/ stderr的
$ sh -c 'sleep 30 & echo payload'
payload
$
这里转到后台sleep 30
起着泄露过程(这在现实中会像dbus-daemon
)的作用和回声是我要运行的实际的事情。这里应该将sleep 30 & echo payload
视为一个原子不透明的示例命令。
上述命令是细并立即返回作为外壳的,并且还睡眠的stdout/stderr的是一个PTY。但是,捕获命令的输出时,管道/文件(测试跑步想要的一切保存到一个日志,毕竟),整个命令挂起:
$ sh -c 'sleep 30 & echo payload' | cat
payload
# ... does not return to the shell (until the sleep finishes)
现在,这可能是固定的一些相当复杂的外壳魔法,它决定了从/proc/$$/fd/{1,2}
开始的stdout/err的FD,迭代ls /proc/[0-9]*/fd/*
并杀死每个同样具有stdout/stderr的进程。但是这涉及很多脆弱的shell代码和昂贵的shell字符串比较。
有没有办法以更优雅和更简单的方式清理这些泄漏的后台进程? setsid
没有帮助:
$ sh -c 'setsid -w sh -c "sleep 30 & echo payload"' | cat
payload
# hangs...
注意进程组/会话和杀害他们批发是不够的,因为泄漏的进程(如DBUS守护进程)通常setsid自己。
P.S.我只能在这些环境中假设POSIX shell或bash;没有Python,Perl等。
谢谢你提前!
以下的工作,但我不服气它回答你的问题:'sh -c'{sleep 30 |猫 ; }&{echo payload |猫 ; }'' –
谢谢,但我没有专门寻找睡眠和回声的解决方案;这只是一个示例命令,用于“某些命令泄漏后台命令”的情况。我对这个问题做了一些澄清。 –
我发现了一个初始近似值:'$ setsid -w sh -c'sleep 30&echo payload; RC = $ ?; for p in $(pgrep --pgroup 0);做[$ p = $$] ||杀死$ p;完成;退出$ RC'|只要使用'kill - - $$'就太过分了,因为它也会杀死shell。 –