Como exibir a saída do comando ao mesmo tempo que a analisa?

0

Eu tenho dois comandos, build e deploy . Atualmente executo build manualmente, analiso sua saída usando meus próprios olhos e uso um valor que encontro na saída como um argumento para deploy . O processo parece algo como:

$ 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 é realmente Packer , para o astuto)

Gostaria de juntar esses dois passos em um script. O esboço geral incluiria o seguinte:

  • Executar build
  • Verifique se o status de saída foi 0 e se a saída continha a string "AMIs foram criadas", caso contrário, cancele
  • Extraia o número da AMI ( ami-19601070 ) da saída
  • Executar deploy ami-19601070

Estou tentando encontrar a melhor maneira de conectar tudo, de preferência usando um script de shell, mas estou preso em como ajustar a saída para dois padrões separados, enquanto, idealmente, ainda streaming de todos os stdout / stderr mensagens para o terminal como os comandos são executados. Eu estou querendo saber se eu deveria abandonar a idéia de fazer isso em um script de shell e, em vez disso, escrever um pequeno script Python para fazer isso.

    
por smitelli 24.11.2015 / 17:58

4 respostas

5

Parece um trabalho para tee :

build | tee /some/file
ami_name=$(do_something_to /some/file)
deploy "$ami_name"
    
por 24.11.2015 / 18:01
2
 deployArgs='build | tee /dev/tty  | extractDeployArgs' &&
    deploy "$deployArgs" #won't run unless extractDeployArgs suceeded

tee /dev/tty será impresso diretamente no terminal e passará a saída para o próximo comando no pipeline ao mesmo tempo.

(Sinta-se à vontade para substituí-lo por algum outro arquivo (ou /dev/fd/"$someFileDescriptor" se você precisar que a saída lateral vá para $someFileDescriptor ))

Em shells mais avançados ( ksh , bash , zsh , mas não em dash ) você pode set -o pipefail para garantir que o pipeline falhe se algum de seus links falhar (útil se extractDeployArgs não posso dizer de sua entrada se build teve ou não).

    
por 24.11.2015 / 18:09
0
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
    
por 24.11.2015 / 22:23
0

Se o seu interesse estiver em uma determinada string de saída, você poderá executá-lo da seguinte forma:

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

O primeiro grep seleciona apenas as linhas em sua saída que relatam que as AMI foram criadas ou ami #. A saída é verificada para "AMIs foram criadas" e, se presente, analisa o ami- # fora de sua saída relevante e a usa para implantar.

    
por 24.11.2015 / 19:05