2016-02-19 2 views
0

Я выполняю программу, которая подключается к внешнему серверу из python.
Если пользователь не аутентифицирован, программа запрашивает имя пользователя и пароль.Подпроцесс убийства после первой строки

Вот как выход из подпрограммы выглядит:

Authentication Required 

Enter authorization information for "Web API" 

<username_prompt_here> 
<password_prompt_here> 

Я хочу убить подпроцесс сразу после «Требуется проверка подлинности» печатается, но проблема в том, что мой код работает неправильно - подпроцесс просит полномочий и после пользователь предоставляет его, подпроцесс убит.

Вот мой код:

with subprocess.Popen(self.command, stdout=subprocess.PIPE, shell=True, bufsize=1, universal_newlines=True) as process: 
    for line in process.stdout: 
     if 'Authentication Required' in line: 
      print('No authentication') 
      process.kill() 
     print(line) 

Что я делаю неправильно?

+0

Можете ли вы опубликовать полный код? или он завершен? Я не вижу, где вы запрашиваете пользователя для имени пользователя и пароля. –

+0

Я не подскажу - подпрограмма это делает (посмотрите на attatched output). – Djent

+0

, и вы хотите немедленно удалить этот процесс после строки, требуемой для проверки подлинности? –

ответ

1

Что я делаю неправильно?

Ваш код нормально (если вы хотите, чтобы убить подпроцесс после 'Authentication Required' линии независимо от ее положения), если дочерний процесс переполняется стандартный вывод буфера во времени. См Python: read streaming input from subprocess.communicate()

Наблюдаемое поведение указывает на то, что ребенок использует режим буферизации блоков и, следовательно, ваш родительский сценарий видит 'Authentication Required' линию слишком поздно или что убийство оболочки с process.kill() не убивает своих потомков (процессы, созданные с помощью команды) ,

Чтобы обойти это:

  • Посмотреть, можно ли передать аргумент командной строки, такие как --line-buffered (принятой grep), чтобы заставить строку режима буферного
  • Или видит ли stdbuf, unbuffer, script Утилиты работают в вашем случае
  • Или предоставить псевдо-tty, чтобы обмануть процесс, подумав, что он работает в терминале напрямую - он также может принудительно активировать режим буферизации.

примеры См код в:


И - не всегда я хочу убить Progra м после первой линии. Только если первая строка «Требуется аутентификация»

Предполагая, что проблема буферизации блоков фиксирована, чтобы убить дочерний процесс, если первая строка содержит Authentication Required:

with Popen(shlex.split(command), 
      stdout=PIPE, bufsize=1, universal_newlines=True) as process: 
    first_line = next(process.stdout) 
    if 'Authentication Required' in first_line: 
     process.kill() 
    else: # whatever 
     print(first_line, end='') 
     for line in process.stdout: 
      print(line, end='') 

Если shell=True необходимо в вашем случае затем см. How to terminate a python subprocess launched with shell=True.

Смежные вопросы