Как выполнить сценарий bash изнутри python неблокирующим образом и позволить увидеть его вывод? - PullRequest
0 голосов
/ 28 января 2020

В системе Ubuntu Linux я хочу запустить скрипт bash из скрипта python. Мне нужно запустить его неблокирующим образом, чтобы скрипт python сообщал обо всех выходных данных скрипта bash в стандартный вывод.

Я нашел очень похожий вопрос здесь , который не работает для меня (конечно). Вот мой bash скрипт testbash.sh, который просто печатает ряд чисел:

#!/bin/bash
i=0

while [ $i -le 10 ]
do
  echo Number: $i
  ((i++))
  sleep 1
done

Вот скрипт python:

import sys
import time
from subprocess import PIPE, Popen
from threading  import Thread

try:
    from queue import Queue, Empty
except ImportError:
    from Queue import Queue, Empty  # python 2.x


ON_POSIX = 'posix' in sys.builtin_module_names

def enqueue_output(out, queue):
    for line in iter(out.readline, b''):
        queue.put(line)
    out.close()

p = Popen(['.','testbash.sh'], stdout=PIPE, bufsize=1, close_fds=ON_POSIX, shell=True)
q = Queue()
t = Thread(target=enqueue_output, args=(p.stdout, q))
t.daemon = True # thread dies with the program
t.start()

# read line without blocking
running = True
while running:
    time.sleep(1)
    try:
        line = q.get_nowait() # or q.get(timeout=.1)
    except Empty:
        print('no output yet')
    else:
        # got line
        print(line)

При запуске этого скрипта я получить только вывод «пока нет» и фактический вывод из сценария bash.

Я хочу, чтобы сценарий python работал до тех пор, пока выполняется сценарий bash, перенаправляя вывод из сценария bash в стандартный вывод python (чтобы я видел цифры 1 ..10 через каждые 1-2 секунды), а через ~ 10 секунд сценарий python останавливается. Мне также нужно проверить, нормально ли работает скрипт bash fini sh или с ошибкой

Чего мне не хватает? Сценарий действительно запущен? Как получить его вывод? Как проверить код выхода?

1 Ответ

1 голос
/ 28 января 2020

Необходимо внести несколько изменений, в частности, вызов сценария оболочки:

import sys
import time
from subprocess import PIPE, Popen
from threading  import Thread

try:
    from queue import Queue, Empty
except ImportError:
    from Queue import Queue, Empty  # python 2.x


ON_POSIX = 'posix' in sys.builtin_module_names

def enqueue_output(out, queue):
    for line in iter(out.readline, b''):
        queue.put(line.decode('ascii'))
    out.close()

p = Popen(['./testbash.sh'], stdout=PIPE, bufsize=1, close_fds=ON_POSIX, shell=True)
q = Queue()
t = Thread(target=enqueue_output, args=(p.stdout, q))
t.daemon = True # thread dies with the program
t.start()

# read line without blocking
while t.is_alive():
    time.sleep(1)
    try:
        line = q.get_nowait() # or q.get(timeout=.1)
    except Empty:
        print('no output')
    else:
        # got line
        print(line, end='')

p.wait()
print(f'returncode = {p.returncode}')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...