Как сигнализировать процессу оболочки во время выполнения скрипта? - PullRequest
0 голосов
/ 26 июня 2018

Большинство обучающих программ по консольным приложениям, которые я видел, имеют представление о записи в консоль.Например:

C# => Console.WriteLine(...)
node.js => console.log(...)
ruby/python => print ...
etc. etc.

Я понимаю, что запись в консоль в основном означает запись в поток stdout, и что среда выполнения (то есть node.js или CLR для C #) знает, что делать с этим стандартом.=> В этом случае записывает на экран терминала.

Использование языка сценариев на основе терминала (на самом деле мне нужно сделать это в сценарии .bat, но мне также интересно узнать, как использовать .sh script), как я могу сохранить стандартный вывод дочернего процесса в переменную?Итак, что-то вроде этого:

script1Output=(first instance of stdout from script1)
script2output=(first instance of stdout from script2)
etc

Скрипт 1 и Скрипт 2 - это долго работающие консольные приложения.Мне нужно подождать, пока некоторые данные будут кэшированы в сценарии 1, прежде чем запускать сценарий 2.

1 Ответ

0 голосов
/ 26 июня 2018

Интерпретатор cmd использует for /F для захвата и анализа выходных данных команды.См. for /? в консоли cmd для получения полной информации.По сути, вы бы сделали что-то вроде этого:

@echo off & setlocal

for /f "usebackq delims=" %%I in (`cmd /c "child1.bat"`) do (
    echo(%%~I
    set "output=%%~I"
    setlocal enabledelayedexpansion

    rem # If !output! contains "Test String"...
    if not "!output!"=="!output:Test String=!" (

        rem # Do this to spawn child2.bat asynchronously
        start /b "" "child2.bat"

        rem # Or if you prefer child2.bat to block...
        rem # call "child2.bat"
    )
    endlocal
)

В сценарии .sh (предположительно с #!/bin/bash вверху) вы можете записать вывод в переменную гораздо проще.

output=$(command)
echo $output

Но я предполагаю, что это совсем не то, что вам нужно, поскольку echo $output никогда не срабатывает, пока command не завершится, верно?В этом случае, может быть, вы могли бы использовать awk, чтобы отслеживать вывод command и запускать процесс, когда обнаружен соответствующий вывод?

# limit charset to optimize execution efficiency
export LC_ALL=C

bash -c ./child1.sh | awk '1;/Test String/ { system("(bash -c ./child2.sh) &") }'

Или чуть сложнее, вы можете обрабатывать в чистом bashбез зависимости от awk:

export LC_ALL=C

bash -c ./child1.sh | while IFS='' read -r line; do {
    echo $line
    [[ $line =~ "Test String" ]] && ./child2.sh &
}; done
...