我在Python中重写了一个函数来替换os.system(),以确保记录进程的输出。
def log_system(self, cmd: str):
cmd = cmd.rstrip(' ')
if cmd[-1] == '&' and cmd[-2] != '&':
cmd = cmd[:-1]
# Redirects standard error to standard output for logging
executing = os.popen('bash -c' + '"' + cmd + '"' + '>/dev/stdout 2>&1 &')
else:
executing = os.popen('bash -c' + '"' + cmd + '"' + '>/dev/stdout 2>&1')
res = executing.readlines()
ret = executing.close()
if len(res) > 0: # print message if have some content
msg = ''.join(res)
if ret is None: # None means process return successfully
log.i(msg) # print stdout
else:
log.e(f'cmd execute failed: {cmd}\n' + msg) # print stderr
原始语句运行良好,它是:
os.system("ps ax | grep 'tcpdump' | grep -v grep | kill `awk '{print $1}'` ")
使用log_system()后,shell脚本可能是:
bash -c "ps ax | grep 'tcpdump' | grep -v grep | kill `awk '{print $1}'`"
但是,当我执行代码时,它阻塞了,我不知道发生了什么。
我使用终端重试,此脚本是非阻塞的:
ps ax | grep 'tcpdump' | grep -v grep | kill `awk '{print $1}'`
这也阻碍了
bash -c "ps ax | grep 'tcpdump' | grep -v grep | kill -9 $(awk '{print $1}')"
bash -c "ps ax | grep 'tcpdump' | grep -v grep | kill `awk '{print $1}'`"
2条答案
按热度按时间nkoocmlb1#
kill
命令不接受标准输入上的进程ID,它必须作为参数提供。具体来说,当前的命令片段(不管
kill
标准输入中输入了什么)将永远挂起,因为awk
正在等待 * 其 * 标准输入(终端),实际上:因此,命令需要类似于:
$()
捕获其内容的标准输出并将其用作kill
的命令行参数。但是,您可能还想看看我前面的回答之一。有更好的工具可用于查找和/或杀死进程,如
pgrep
和pkill
。如果您有这些工具,它们通常是比尝试使用ps/grep/awk
管道更好的选择。insrf1ej2#
您正在从python处理的字符串切换到bash解释的字符串。
当我执行代码时,它会阻塞
反勾引用似乎是麻烦。
考虑使用
$(awk ... )
bash语法。考虑使用
... | find /usr/bin/kill
,以便stdin上的PID将被终止。让程序(如tcpdump)在退出时进行清理。最初发送默认的SIGTERM,而不是SIGKILL。然后休眠至少一秒钟,* 然后 * 如果它仍然没有退出,您可以杀死-9。