ループ内でプログラムを実行して終了値を確認するシェルスクリプト

ループ内でプログラムを実行して終了値を確認するシェルスクリプト

シェルスクリプトでこれを行うには:

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を実行しています

ベストアンサー1

#! /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場合)、出力が128KiBを超えると失敗します。yashsh

または、次のものを使用できます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 $?;
}

おすすめ記事