Разбейте скрипт bash на отдельные команды и запускайте их по очереди. - PullRequest
2 голосов
/ 01 июня 2019

Я хочу иметь возможность запускать скрипт оболочки bash из Python (используя что-то вроде subprocess.Popen), но отображать в моем графическом интерфейсе команду, которая будет выполняться вместе с выводом в режиме реального времени, как он поступает в stdout и stderr. GUI должен показывать Input (newline) Output (newline) Input и так далее. В настоящее время я могу реализовать его для однострочных команд bash, но мне нужен более сложный парсер для многострочных команд. Вот мой код, который работает только для простых однострочных команд в bash.

test.sh:

ping -c 2 www.google.com

if [ "abc" = "ghi" ]; then
    echo expression evaluated as true
else
    echo expression evaluated as false
fi

Файл моего питона:

with open("test.sh", "r") as script:
    for line in script:
        if not line.strip().startswith('#') and not line.strip() == "":
            print("Debug: Running " + line.strip() + " ...")
            proc = subprocess.Popen(shlex.split(line), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            while True:                        
                output = str(proc.stdout.readline().strip().decode()) + ""
                err = str(proc.stderr.readline().strip().decode()) + ""
                if output == '' and proc.poll() is not None:
                    print("Debug: Command completed...")
                    time.sleep(1)
                    break
                if output: 
                    # Code for updating a Gtk TextView buffer
                    GLib.idle_add(self.updateConsoleText, output + "\n")
                if err:
                    # Code for updating a Gtk TextView buffer
                    GLib.idle_add(self.updateConsoleText, err + "\n")

Как и ожидалось, он не работает с многострочным кодом, который включает if-else, loops, heredoc s и т. Д. Я ищу синтаксический анализатор bash, который по крайней мере распознает, когда команда заканчивается, и может разделить скрипт bash на отдельные команды в тех случаях, когда используются многострочные команды.

Как вы думаете, вы могли бы помочь мне найти такую ​​библиотеку / инструмент?

1 Ответ

2 голосов
/ 01 июня 2019

Вы можете использовать команду trap.

Вот небольшой пример, демонстрирующий концепцию:

#!/bin/bash

# redirect stderr to a logfile
exec 2>/tmp/test.log

# print commands and arguments at execution
set -x

# set trap for every step, sleep one second.
# "sleep 1" could be every bash command
trap "sleep 1" DEBUG

echo -n "Name: "; read -r name
echo -n "Age: "; read -r age
echo "$name is $age years old"

Параллельно с запуском этого скрипта вы можете использовать tail -f /tmp/test.log для отслеживания вызова команд и их параметров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...