Убейте подпроцесс. Откройте дочерний элемент с помощью CTRL + c - PullRequest
0 голосов
/ 02 июля 2019

Если я наберу эту команду в терминале от имени пользователя root, скажем, от пользователя bob:

su - bob -c "cd /home ; ping www.google.com"

Пинг непрерывно, пока я не нажму CTRL+c. Я пытаюсь имитировать подобное поведение. Мой установочный скрипт запускается до того, как я могу установить pexpect и другие вещи. Пинг выполняется в дочернем элементе подпроцесса из-за su - bob. Это означает, что Popen.kill() не работает. Я провел некоторое исследование и нашел здесь несколько ответов на вопрос о группировке с PID, а затем об убийстве группы.

Вопрос : Я хотел бы понять, почему communicate не отправляет CTRL+c и не завершает ожидаемый мной подпроцесс, показывает, что я не понимаю некоторые основы.

import time
import subprocess

user = 'bob'    
cmd_list = ['su', '-', user, '-c','cd /home/ ; ping www.google.com ; exit']

p = subprocess.Popen(
    cmd_list,
    stdin=subprocess.PIPE,
)
print("Wait 2s...")
time.sleep(2)
print("2s passed.")

try:
    # Send CTRL+c to kill the child process from su -
    p.communicate(input='\0x03', timeout=3)
    print("CTRL+c killed the process")
except subprocess.TimeoutExpired:
    print('Timeout occured')
p.kill()

1 Ответ

2 голосов
/ 02 июля 2019

.communicate использует stdin, вам нужно отправить сигнал с помощью send_signal.

попробуйте это:

import time
import subprocess
import signal

user = 'bob'
cmd_list = ['su', '-', user, '-c','cd /home/ ; ping www.google.com ; exit']

p = subprocess.Popen(
    cmd_list,
    stdin=subprocess.PIPE,
)
print("Wait 2s...")
time.sleep(2)
print("2s passed.")

try:
    # Send CTRL+c to kill the child process from su -
    p.send_signal(signal.SIGINT)
    print("CTRL+c killed the process")
except subprocess.TimeoutExpired:
    print('Timeout occured')
p.kill()
...