подпроцесс.Popen(«bash file.sh «): как уничтожить скрипт Bash и все его фоновые задания

#python #bash #unix #subprocess

#python #bash #unix #подпроцесс

Вопрос:

У меня есть скрипт bash, который запускает несколько процессов в фоновом режиме. Я могу закрыть их все, используя Ctrl-C, если я запущу скрипт в терминале bash.

Когда я запускаю скрипт с помощью подпроцесса.Popen, я не могу их закрыть. Я могу изменить оба сценария, чтобы он работал.

Я просто хочу открыть несколько процессов в bash и отправить им сигнал завершения, когда я захочу закрыть. Я могу попробовать разные подходы.

Скрипт Bash

 #!/bin/bash

ping -i 5 google.com amp;
ping -i 4 example.com amp;

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")
 

Комментарии:

1. Почему бы не передать тайм-аут ping также: ping -t 5 google.com ?

2. Пинги предназначены для демонстрации. Они печатаются в стандартный вывод, поэтому я понимаю, работают ли они все еще или нет.

3. Я не вижу симптомов, о которых вы сообщаете. Ctrl-C для меня убивает все процессы в любом случае (shell ping ping и py shell ping ping), поскольку все они являются частью одной и той же группы процессов. (Примечание: ping отличается от типичных команд здесь тем, что он устанавливает обработчик SIGINT, поэтому обычная семантика игнорирования SIGINT в списках команд асинхронной оболочки не применяется).

4. @pilcrow Я не хочу завершать программу Python. Я хочу завершить rest во время работы программы Python.

Ответ №1:

Вы должны перехватить SIGTERM и убить дочерние процессы. Добавьте приведенный ниже код перед wait тем, как в файл bash. Также вам необходимо отправить SIGTERM или использовать функцию завершения Popen объекта.

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

trap trap_sigterm SIGTERM