У меня есть сценарий bash, который выполняется вечно и печатает некоторую информацию с различными интервалами. Для простоты; предположим, что это мой bash скрипт; давайте назовем это mybashscript.sh
#!/bin/bash
while :
do
echo "The loop has printed"
sleep 5
done
Это просто из соображений простоты; Мой настоящий сценарий не так прост. (У меня есть около 30 из этих не разветвленных, не запускаемых в оболочку bash сценариев.)
Я хочу написать python программу, которая будет;
- Запустить это bash script
- Получить вывод из stdout сценария bash; и проанализировать его (для простоты; скажем, я хочу добавить строку
[python]
в начале каждой строки) и распечатать его. - Завершит работу сценария bash, когда сценарий python прекращается.
- В то же время; ответить на строки в python stdin (для простоты; допустим, я хочу пропустить песню, когда есть ввод с клавиатуры на stdin.
У меня есть следующая программа для этого; давайте назовите это mywrapper.py
(я использую здесь команду mpc next
; потому что мне довольно легко понять, вызвано ли это; у меня включены наушники)
#!/bin/env python
import os
import re
import sys
import threading
import subprocess
def response():
""" Just one function to check if functions work """
subprocess.call(['mpc', 'next'],
stdin=subprocess.DEVNULL,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
def listen(inp):
""" Respond to stdin """
for line in inp:
response()
if __name__ == '__main__':
# Test the response function
response()
# Start the infinite loop
SCRIPT = subprocess.Popen('/tmp/mybashscript.sh',
stdin=subprocess.DEVNULL,
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL)
# Start the listener
LISTEN = threading.Thread(target=listen,
args=(sys.stdin))
LISTEN.start()
# Respond to lines in the script
while True:
LINE = SCRIPT.stdout.readline()
# If the script terminated; get out of loop to terminate program
if not LINE:
break
print('[python]' + str(LINE))
# Need this to stop buffering
sys.stdout.flush()
Однако; listen
ничего не делать. Функция ответа работает нормально; при первом вызове. Как я могу изменить мой python сценарий для ответа на ввод?
Кроме того, для остановки этой программы требуется два прерывания клавиатуры. Как я могу скажите, будет ли SIGTERM убивать также все дочерние процессы?
Чтобы избежать проблемы XY, вот именно то, что я пытаюсь сделать;
- Я пытаюсь написать программу, которая будет взаимодействовать с другой программой. Я нахожусь на Linux, и я хочу использовать i3blocks для отображения информации на моем экране, когда я использую i3 / sway.
- Я хочу используйте опцию постоянства, которая изменит Текст, который i3blocks отображает только тогда, когда связанный скрипт печатает новую строку.
- У меня есть скрипт da sh, называемый
music
, который печатает имя текущей воспроизводимой песни, и печатает новую строку только при изменении песни. Сюда; мне не нужно опрашивать информацию и не нужно постоянно обновлять текст, если я не играю какие-либо песни. - Я написал оболочку python, которая называется
sysinfo-i3bar
; в основном форматирование вывода строки так, чтобы оно было в формате json; как я могу контролировать цвета и прочее. (Причина, по которой я не выполняю полный json синтаксический анализ сценария da sh, заключается в том, что я хочу повторно использовать исходный сценарий; но в других программах, таких как polybar ; наличие одного информационного сценария и тогда полезно иметь несколько оберток для нескольких случаев) Пока все хорошо. - Если я нажму на экранный блок на i3blocks; символ в зависимости от нажатой кнопки, например, 1 для щелчка левой кнопкой мыши или 2 для щелчка правой кнопкой мыши, отправляется на стандартный ввод запущенного сценария. То, что я хочу сделать, это ответить на эти события; и, например, запустить
mpc toggle
, когда область будет нажата. Я не могу понять, как это сделать в настоящее время. - Я пытаюсь ответить на stdin в оболочке; а не оригинальный скрипт da sh, потому что другие строки состояния не работают так. (Polybar просто нужен собственный синтаксис, обернутый вокруг текста для выполнения команды при щелчках, как это видно в моей оболочке
sysinfo-polybar
.)
В конце концов; Я хотел бы упаковать эти сценарии / оболочки и выпустить его для сообщества. Я ценю любую помощь.