mdfind出力をbashのif else文にリダイレクトする方法

mdfind出力をbashのif else文にリダイレクトする方法

入力ファイルにリストされているいくつかのファイルをコンピュータ全体で見て、そのファイルを特定のフォルダにコピーするスクリプトを作成しようとしています。これまで、forループとmdfind "command" xargsを使用すると、すべてがうまく機能します。ただし、mdfindが見つからなかったファイルのリストを含む出力ファイルを生成するためにifステートメントを追加すると、問題が発生します。これは私の実際のコードです。

if [ $# -eq 0 ]
then
echo "Please introduce the name of the input file after runnig the command. 
For this script you need an INPUT.txt file containing only the list of the 
samples you want to copy." 
else
for i in $(cat $1); 
do mdfind "kMDItemDisplayName == $i*.ab1" | xargs -I '{}' cp '{}' 
/Users/xxxxx/xxxxx/xxxxx/xxxxxxx/test_moving/; 
if [ $? -eq 0 ] 
then
echo $i >> extractions_not_found.txt
else
echo $i >> extractions_found.txt
fi
done
fi

出力をリダイレクトするために$?を使用しています。

 mdfind "kMDItemDisplayName == $i*.ab1" | xargs -I '{}' cp '{}' /Users/xxxxx/xxxxx/xxxxx/xxxxxxx/test_moving/;

ただし、入力ファイルにリストされているファイルのいずれかが見つからない場合でも、常に= 0です。

誰もがエラーがどこにあるかを理解するのに役立ちますか?

ありがとうございます!

ベストアンサー1

を実行した後mdfind ... | xargs cp ...のエラーコードはパイプラインの最後のコマンドなので、$?エラーコードです。実行されたコマンドが失敗した場合は123を返しますが、出力が生成されない場合は何もしないため失敗しません。xargsxargsmdfindxargs

しかし、Bashでは、最後のパイプですべてのコマンドの終了コードを見つけることができます。配列変数 PIPESTATUS。最初のコマンドの終了コードは${PIPESTATUS[0]}次のとおりです。

$ false | true | xargs false
$ echo "${PIPESTATUS[*]}"
1 0 123

したがって、$?終了ステータスを提供するメソッドを使用する代わりに、終了ステータスを提供するメソッドを使用できます。または、バッチを別の変数に保存し、両方をテストします。 ( )xargs${PIPESTATUS[0]}mdfindsaved=("${PIPESTATUS[@]}")

または、パイプラインで最後に失敗したコマンドのいずれかが失敗した場合は、そのコマンドの終了コードを提供するためにset -o pipefail使用します。$?false | true結果は$?=1。)

おすすめ記事