Убить процесс sudo/root с помощью pexpect

Учитывая порожденный pexpect процесс, открытый с помощью sudo, например:

#!/usr/bin/env python
import pexpect

cmd = ['sudo', 'bash', '-c', '"some long-running sudo command"']
cmd = ' '.join(cmd)
child = pexpect.spawn(cmd, timeout=60)

i = child.expect([
  'success',
  'error'])
if i == 0:
  print('ok')
else:
  print('fail')
  # insert code here

Как бы я убил этот процесс в случае неудачи (или успеха, если уж на то пошло)?

Я пробовал следующее (заменяя # insert code here):

child.kill(0)
child.close(force=True)

Оба выдают следующую ошибку, что имеет смысл, поскольку скрипт Python не является корневым процессом и пытается убить что-то, что является корневым процессом.

Traceback (most recent call last):
  File "./myscript.py", line 85, in <module>
    requires_qemu()
  File "./myscript.py", line 82, in requires_qemu
    child.close(0)
  File "/usr/lib/python2.7/site-packages/pexpect/__init__.py", line 747, in close
    raise ExceptionPexpect('Could not terminate the child.')
pexpect.ExceptionPexpect: Could not terminate the child.

Невозможно запустить скрипт от имени пользователя root из-за прав доступа к файлам (запуск с общего диска NFS, где доступ root заблокирован)


person stephenfin    schedule 03.05.2014    source источник
comment
kill(0) скорее всего ничего не сделает - нет сигнала 0. Обычными для завершения не отвечающего процесса являются SIGTERM (15) и SIGKILL (9). Номера сигналов доступны как константы в модуле signal.   -  person Thomas K    schedule 05.05.2014


Ответы (1)


Используйте sudo, чтобы убить его как root:

subprocess.call(['sudo', 'kill', str(child.pid)])
person poolie    schedule 03.05.2014
comment
Умный. Однако возможно ли это сделать в контексте pexpect? - person stephenfin; 03.05.2014
comment
Конечно, вы также можете использовать pexpect.spawn(), но просто subprocess кажется чище, поскольку вы не используете никаких интерактивных функций. - person poolie; 04.05.2014