Сценарий оболочки для выполнения программ в цикле и проверки их значений выхода

Как мне сделать это в сценарии оболочки:

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;}
}

Я использую Ubuntu

0
21.04.2016, 15:35
2 ответа
#! /bin/sh -
i=0; while [ "$i" -lt 1000 ]; do
  cmdA
  cmdB > tempfile || continue
  cmdC < tempfile || break
  i=$((i + 1))
done
rm -f tempfile

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

#! /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

Что бы вы ни делали, вам нужно где-то сохранить этот вывод, так как вы не можете получить статус выхода cmdB , пока он закончился.

Вместо этого вы можете сохранить его в памяти. Если вывод cmdB является текстом, вы можете сделать:

#! /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

Если printf не встроен в ваш / bin / sh (например, если вы ' Мы установили mksh или yash и сделали его sh ), что приведет к сбою при выводе размером более 128 КБ.

Или вместо этого вы можете использовать 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 $?;
}
1
28.01.2020, 02:48

Я бы добавил, что если ваша оболочка - bash, тогда $? также доступен. На странице руководства: «Расширяется до состояния последнего выполненного конвейера переднего плана», что означает, что он содержит статус выхода последнего выполненного процесса.

    #!/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;}
    }

Приведенный выше код не фиксирует статус выхода applicationC, но это будет примерно так:

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

Это работает, потому что последним процессом, который завершится, будет applicationC. Если вы используете другую оболочку, проверьте страницу man / info. Есть и другие способы сделать это с помощью && и || операторы тоже.

0
28.01.2020, 02:48

Теги

Похожие вопросы