重複ではないことを願っていますが、見つけて答えようと実写をしました。最初のコマンドが失敗した場合にのみ、生の出力を2番目のコマンドにパイプしたいと思います。
例えば、cat file.txt | command1 || command2
command1 と command2 の両方が STDIN から読み取られます。
私はcommand1がすべてを読みたいのcat file.txt
ですが、それが失敗した場合。 command2ですべての入力を実行したいです。
編集:今私の質問が少し曖昧であることに気づきました。私はcommand1とcommand2が両方ともSTDINから読み取られたと言いましたが、私が意味するのは両方ともcat file.txt
STDOUTを受信したいということです(必ずしも特定のコマンドである必要はありません)。
私の元の希望は、このようなものをエイリアスに入れることだったようです。 5ヶ月が過ぎた今、この問題がどのように解決されたのか覚えていません。 bashスクリプトを書くのが最も可能性が高いです。
答え1
スタック交換へようこそ!ここには良い情報がたくさんあります。まず、ご注意ください。
あなたの注文で私が見た問題は、「質問を引き起こす」ことです。つまり、始める前に答えを知っているとします。
もう少し詳しく見てみましょう。
cat file.txt
「file.txt」の内容はSTDOUTに移動します。
"cat"コマンドがエラーを生成すると、STDERRが実行されます。
コマンドが完了すると終了コードが設定されます。 0 = 成功、その他はエラーです。
ここでの問題は、出力が送信されるまで実行する必要があるかどうかがcommand1
わからないことです。command2
つまり、消えた。
これを比較してみてください:
cat file.txt | sort
これは実際には2つのコマンドです:
1:cat file.txt 1> temp_file
2:sort < temp_file
まあ、実際にはUnixコマンドではありません。ただ説明のためのものです。
1:STDOUTを「tempfile」(つまり、1>部分)に送信します。また、STDERR をコンソールに送信します。
2:sortコマンドを実行し、「tempfile」からSTDINを読み込みます。 2つのコマンドの間に
パイプを置くと、|
一時ファイルは必要ありません。パイプの意味は、STDOUTを「cat」から「sort」のSTDINにリダイレクトすることです。
問題:
STDOUTを他のコマンドのSTDINにリダイレクトしたいのですが、まだどのコマンドがあるのかわからないため、リダイレクトできません。
考えられる解決策を議論する前に、いくつかの背景知識をお知らせします。
Unixには、必要な方法でコマンドを実行する方法があります。気をつけて:
my_command argument1 argument2 && echo "Success" || echo "Failure"
my_command
コンソールでSTDOUTとSTDERRを使用して実行し(そして終了ステータスを返した後)、一方または他のechoを実行します。
&&
「最後のコマンドが成功した場合はこれを実行してください」とは、
||
「最後のコマンドが失敗した場合はこれを実行してください」を意味します
。元のコマンドと非常に似ています。
cat file.txt | command1 || command2
次のように変更します。これは、
cat file.txt && command1 || command2
出力を除いて必要なものすべてを提供します。
Q1:有効な
場合はSTDOUTを読み、STDERRを無視する必要がありますか?同様に、失敗した場合はSTDERRを読み取り、STDOUTを無視する必要がありますか?それとも、両方のコマンドのいずれかがSTDOUTとSTDERRの両方を読み取る必要がありますか?完全性を期すために、両方の質問に答えます。どちらにしても、後で処理するために出力を保存する方法が必要です。通常は一時ファイルです。同じtemp_fileからSTDOUTとSTDERRをキャプチャします。cat file.txt
command1
command2
cat file.txt > /tmp/temp_file 2>&1
STDOUTをtemp_file#1としてキャプチャし、STDERRをtemp_file#2としてキャプチャ:
cat file.txt > /tmp/out_file 2 >/tmp/err_file
質問2:コマンドラインでファイル名を使用できますか
?command1
command2
command1 temp_file
ファイルからのリダイレクトを許可してcommand1
いますか?command2
command2 < temp_file
STDINを実行command1
および/またはcommand2
読みますか?
cat temp_file | command1
注:単語数コマンドは例です。
wc temp_file
cat temp_file | wc
wc < temp_file
2番目の形式は、&& ||に問題のある形式がある可能性があります。完全性のためにここに入れます。
command1
結局、何をすべきか、command2
何をすべきかを決めなければなりません。
これでこれらを組み合わせることができます。
cat file.txt > /tmp/out_file 2>/tmp/err_file && command1 < /tmp/out_file || command2 < /tmp/err_file
その後、一時ファイルを削除すると、目的の
rm /tmp/out_file /tmp/err_file
結果が得られます。
私はここの他の専門家がtemp_fileを使用せずに方法を見つけることができると確信しています。私はプログラミング作業室にいなくても、誰が私のコードを管理するのか分からないので、仕事を簡単で理解しやすくするのが好きです。
答え2
これを行う唯一の方法は、出力をcommand1
ファイルに書き込んで読み取ることですcommand2
。
set -o errexit
command1 < file.txt > 1.out
command2 < 1.out
または
if command1 < file.txt > 1.out
then
command2 < 1.out
fi
もちろん、この時点ではパイプラインの非同期処理の利点は消えます。
答え3
簡単な方法は、ファイルストリームをfile
。
command1 < file || command2 < file
または
if command1 < file; then
echo 'first command was successful'
else
command2 < file
fi
または出力したい内容に応じて同様の構文。
同時に、2つのコマンドで同じファイルストリームを使用するには、同様の方法またはtee
類似の方法を使用する必要があります。これは、返す前に処理を開始する必要があるcommand2
かcommand1
、またはある種のバッファリングを使用する必要があることを意味します。 、おそらくいくつかの信号があるかもしれません。優れた拡張可能なバッファはディスク上のファイルです。