引数として多数のファイルやディレクトリを使用する単純なbash関数を作成しようとしています。そうすべき:
ほぼやりたいことを実行するスクリプトがありますが、並べ替えに失敗します。現状のスクリプトの戻り値は正しいですが、出力は正しくありません(ソートされておらず、重複しています)。示されているように| sort -u
ステートメントのコメントを外すと、出力は正しいですが、戻り値は常に0
です。
N.B.問題を解決するためのより簡単な解決策は歓迎されますが、問題は本当にこれが私が持っているコードで発生する理由についてです。つまり、パイプを追加すると、スクリプトが変数r
をインクリメントするのを停止するように見えるのはなぜですか?
スクリプトは次のとおりです。
function uniqfile
{
local r=0
for arg in "$@"
do
readlink -e "$arg" || (( ++r ))
done #| sort -u ## remove that comment
return $r
}
これはよく知られているbashの落とし穴です。これが原因ですfeature:
パイプラインの各コマンドは、個別のプロセスとして(つまり、サブシェルで)実行されます。
変更された変数がサブシェルに対してローカルであり、親に戻ると表示されないようにします。
これを回避するには、プロセス置換を使用して、パイプラインを回避するようにコードを言い換えます。
for arg in "$@"
do
readlink -e "$arg" || (( ++r ))
done > >(sort -u)