2017-02-06 10 views
1

Я ищу чистый метод для запуска и остановки Java-процессов на основе stdout. В основном я хочу пройти цикл for в Bash, который запускает команду java с входными переменными, контролирует stdout для определенной строки «Results:», а затем убивает тот же процесс, затем переходит к следующему, запускает новый java-процесс и продолжается.Запуск и остановка процесса в скрипте Bash

Я пробовал работать с coproc, но не смог получить ничего близкого к работе, как предполагалось.

+0

введите код, который вы уже писали. –

+0

Это своего рода проблема.Я написал основную логику скрипта (java-команду, которую я пытаюсь запустить, структуру цикла для запуска java-команды на основе файла конфигурации, который находится в каталоге conf и т. Д.). Но когда дело доходит до логики I я перечисляю выше, я даже не знаю, с чего начать ... Я достаточно базовый в своем знании/опыте bash –

ответ

1

Вы можете использовать coproc так:

coproc java … 
grep -q -m1 'Results:' <&$COPROC && kill $COPROC_PID 

Это будет иметь grep чтения с выхода Java и убить его, как только он видит соответствующую строку.


Если вы хотите видеть вывод команды Java вместо того, чтобы делать это молча, используйте tee как для печати на выходе и отправить его в grep … && kill … группе.

coproc java … 
tee <&$COPROC >(grep -q -m1 'Results:' && kill $COPROC_PID) 
+0

Это определенно похоже на путь. По какой-то причине, когда я запускаю команду java, она зависает и никогда не попадает в строку «Результаты:». Если я запускаю команду самостоятельно, она работает нормально. Но с тегом coproc впереди, похоже, он не выводит весь обычный поток stdout. –

+0

Вы видите * любой * вывод при попытке второй формы (с 'tee')? –

+0

Да. Он выводит несколько предупреждений о конфигурации файла журнала (который является нормальным выходом ... ожидается), но затем он просто зависает и никогда не достигает строки «Результаты:». –

1

Я бы использовал screen. Он работает для большинства моих сценариев:

Начало сеанса имени MYJAVA команда

screen -dmS myjava sh -c "/path/to/script.name parameters > /tmp/outfile" 

здесь вы хотели контролировать /TMP/выходной_файл с Баш ... (хвост -f или что-то)

и убить сеанс MYJAVA с

screen -X -S myjava kill 
+0

Итак, в этом контексте я собираюсь предположить, что вы храните команду java в переменной " myjava ", а затем использовать это же обозначение, чтобы убить ту же команду? Где я могу сообщить сценарию КОГДА, чтобы убить процесс ... когда я нахожу правильную строку вывода в stdout ... как он узнает, когда это всплывает? –

+0

О, я вижу. myjava - это имя сеанса экрана. Выберите любое имя. Вы говорите, что будете следить за выводом из баша, поэтому, полагаю, вы уже знаете, как это сделать. Во всяком случае, я немного разъясняю ответ – jaromrax

0

Предполагая, что код вашей Java просто выходит на своем собственном, когда он получает SIGPIPE, вы можете просто перенаправить вывод в grep и имеете grep exit as soon as it sees a match. Assuming you are using a version of Grep that supports the -m option (GNU and BSD Grep grep` выхода после первого матча:

java ... | grep -m 1 'Results:' 

One небольшой улов: из-за буферизации ваша программа java может продолжать работать в течение непродолжительного времени до того, как grep фактически увидит линию «Результаты».


Используя только стандартные grep, вы можете использовать tee как для вывода изображения и выхода после обнаружения любого матча.

java ... | grep 'Results:' | tee | grep -q '.*' 

Это страдает тот же вопрос буферизацию, но усиливается: может не только первый grep придется подождать, прежде чем она на самом деле получает строку «Результаты», но tee может так же нужно ждать, прежде чем она, наконец, получает ту же линию , Кроме того, если линия слишком мала, первый grep никогда не сможет производить больше вывода, требуя, чтобы вы ожидали java, чтобы выйти естественным образом до того, как tee когда-либо видит какой-либо вход.