
シェルスクリプトでこれを行うには:
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を超えると失敗します。yash
sh
または、次のものを使用できます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 $?;
}
答え2
シェルが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ページを確認してください。 &&と||演算子を使用してこれを行う他の方法もあります。