Как отображать вывод команды во время ее разбора?

У меня есть две команды: build и deploy . В настоящее время я запускаю build вручную, анализирую ее вывод своими глазами и использую значение, которое я нахожу в качестве аргумента для deploy . Процесс выглядит примерно так:

 $ build ==> amazon-ebs: amazon-ebs output will be in this color. ... hundreds of lines of output ... ==> Builds finished. The artifacts of successful builds are: --> amazon-ebs: AMIs were created: us-east-1: ami-19601070 $ deploy ami-19601070 ... some more output ... 

( build на самом деле является упаковщиком , для проницательного)

Я хотел бы связать эти два шага вместе в сценарии. Грубая схема будет включать следующее:

  • Запустить build
  • Убедитесь, что статус выхода равен 0 и что вывод содержит строку «AMI были созданы», в противном случае прервать
  • Извлеките AMI-номер ( ami-19601070 ) из вывода
  • Запустить deploy ami-19601070

Я пытаюсь придумать лучший способ соединить все вместе, в идеале, используя сценарий оболочки, но я зациклился на том, как grep выводить два отдельных шаблона, в то время как в идеале все равно передаются все сообщения stdout / stderr терминал при запуске команд. Мне интересно, не следует ли мне отказаться от идеи сделать это в сценарии оболочки и вместо этого написать небольшой скрипт Python для этого.

Звучит как работа для tee :

 build | tee /some/file ami_name=$(do_something_to /some/file) deploy "$ami_name" 
  deployArgs=`build | tee /dev/tty | extractDeployArgs` && deploy "$deployArgs" #won't run unless extractDeployArgs suceeded 

tee /dev/tty будет печататься непосредственно на терминал и одновременно передавать выходные данные следующей команде в конвейере.

(Не стесняйтесь заменять его каким-либо другим файлом (или /dev/fd/"$someFileDescriptor" если вам нужно, чтобы выходной бок поступал в $someFileDescriptor ))

В более продвинутых оболочках ( ksh , bash , zsh , но не в dash ) вы можете set -o pipefail чтобы убедиться, что конвейер extractDeployArgs ошибкой, если какая-либо из его ссылок extractDeployArgs ошибкой (полезно, если extractDeployArgs не может определить из своего ввода, была ли build или нет ).

 tf=$(mktemp) build | tee "$tf" grep -Fq 'AMIs were created' "$tf" && ami=$(grep -o 'ami-[0-9]\+$' "$tf") # you didn't say if `deploy` can handle multiple args or not. # uncomment one of the following: # deploy $ami # for a in $ami ; do deploy "$a" ; done 

Если ваш интерес находится в определенной строке вывода, вы можете запустить его так:

 msg="$(build | grep -e "AMIs were created\|ami-[0-9]*")" if [ -n "$(echo $msg | grep -e "AMIs were created")" ];then ami="$(echo "$msg" | grep -e "ami-[0-9]*" | cut -d ' ' -f 2)" deploy "$ami" else exit 1 fi 

Первый grep выбирает только строки на вашем выходе, которые сообщают AMI, или ami- #. Вывод проверяется на наличие «AMIs», и, если он присутствует, анализирует ami- # из вашего соответствующего вывода и использует его для развертывания.