Script de shell para executar programas em um loop e verificar seus valores de saída

0

Como faço isso em um script de shell:

for (int i=0;i<1000;i++) {

   run applicationA
   run applicationB
   if (retvalFromApplicationB!=0) {continue;}
   else {pipe ouptut (stdout) from applicationB to (stdin of) (and start) applicationC}
   if (retvalFromApplicationC!=0) {break;}
}

Estou executando o Ubuntu

    
por Bwawhwmopoloin 21.04.2016 / 13:02

2 respostas

1

#! /bin/sh -
i=0; while [ "$i" -lt 1000 ]; do
  cmdA
  cmdB > tempfile || continue
  cmdC < tempfile || break
  i=$((i + 1))
done
rm -f tempfile

Se você não pode limpar o diretório atual com arquivos temporários, você pode fazer:

#! /bin/sh -
i=0; while [ "$i" -lt 1000 ]; do
  cmdA 3>&- 4<&-
  tmp=$(mktemp) || exit
  exec 3> "$tmp" 4< "$tmp"
  rm -f "$tmp"
  cmdB >&3 3>&- 4<&- || continue
  cmdC <&4 3>&- 4<&- < tempfile || break
  i=$((i + 1))
done
exec 3>&- 4<&-
rm -f tempfile

Não importa o que você faça, você precisará armazenar essa saída em algum lugar, pois não poderá obter o status de saída de cmdB até que tenha terminado.

Você pode armazená-lo na memória. Se a saída de cmdB for texto, você poderia fazer:

#! /bin/sh -
i=0; while [ "$i" -lt 1000 ]; do
  cmdA
  output=$(cmdB > tempfile && echo .) || continue
  output=${output%.}
  printf %s "$output" | cmdC || break
  i=$((i + 1))
done

Se printf não foi criado em /bin/sh (por exemplo, se você instalou mksh ou yash e fez sh ), isso falhará para uma saída maior que 128 KiB.

Ou você pode usar perl :

#! /usr/bin/perl
for ($i = 0; $i < 1000; $i++) {
  system "cmdA";
  $output = 'cmdB';
  next if $?;
  open TO_C, "|-", "cmdC" or last;
  print TO_C $output;
  close TO_C;
  last if $?;
}
    
por 21.04.2016 / 13:15
0

Gostaria de acrescentar que se o seu shell é bash, então $? também está disponível. A partir da página man: "Expande para o status do pipeline de primeiro plano executado mais recentemente", que é uma maneira de dizer que ele mantém o status de saída do último processo executado.

    #!/bin/bash
    for (int i=0;i<1000;i++) 
    {
       run applicationA
       retvalFromApplicationA = $?

       run applicationB
       retvalFromApplicationB = $?

       if (retvalFromApplicationB!=0) {continue;}
       else {pipe ouptut (stdout) from applicationB to (stdin of) (and start) applicationC}
       if (retvalFromApplicationC!=0) {break;}
    }

O código acima não captura o status de saída de applicationC, mas seria algo como:

applicationB | applicationC
if [ $? -eq 0 ]; then ...

Isso funciona porque o último processo a sair seria o applicationC. Se você estiver usando um shell diferente, verifique a página man / info. Existem outras maneiras de fazer isso com o & & e || operadores também.

    
por 21.04.2016 / 16:23