【问题标题】:subprocess.Popen("bash file.sh"): how to kill the Bash script and all its background jobssubprocess.Popen("bash file.sh"): 如何杀死 Bash 脚本及其所有后台作业
【发布时间】:2021-04-20 11:03:20
【问题描述】:

我有一个在后台运行多个进程的 bash 脚本。如果我在 bash 终端中运行脚本,我可以使用 Ctrl-C 将它们全部关闭。

当我使用 subprocess.Popen 运行脚本时,我无法关闭它们。我可以修改这两个脚本以使其正常工作。

我只想在 bash 中打开多个进程,并在我想关闭时向它们发送终止信号。我可以尝试不同的方法。

Bash 脚本

#!/bin/bash

ping -i 5 google.com &
ping -i 4 example.com &

wait

示例 Python 脚本:

import subprocess
import signal

command = "bash script.sh"
p = subprocess.Popen(command.split())

print("Started")
try:
  p.wait(5) # waits 5 seconds
except:
  print("Kill")

  # These just terminates script.py but pings still working
  #p.kill()
  #p.terminate()
  p.send_signal(signal.SIGINT)

p.wait() # does not wait
print("Ended")

【问题讨论】:

  • 为什么不将超时也传递给pingping -t 5 google.com
  • Ping 用于演示。这些正在打印到标准输出,所以我知道它们是否仍在运行。
  • 我没有看到您报告的症状。在这两种情况下(shell+ping+ping 和 py+shell+ping+ping),我的 Ctrl-C 都会杀死所有进程,因为它们都是同一个进程组的一部分。 (注意:ping 与此处的典型命令不同,它安装了一个 SIGINT 处理程序,因此 ignoring SIGINT in asynchronous shell command lists 的正常语义不适用。
  • @pilcrow 我不想终止 Python 程序。我想在 Python 程序运行时终止休息。

标签: python bash unix subprocess


【解决方案1】:

您必须捕获 SIGTERM 并杀死子进程。在 bash 文件中的 wait 之前添加以下代码。您还需要发送 SIGTERM 或使用 Popen 对象的终止功能。

function trap_sigterm() {
    pkill -SIGINT -P $$  # Kill child processes of $$ (this)
    exit
}

trap trap_sigterm SIGTERM

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-31
    • 1970-01-01
    • 2015-04-02
    • 2014-08-09
    • 1970-01-01
    • 2016-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多