GNU/Linux >> Linux の 問題 >  >> Linux

ループ出力のパイピングはローカル変数の変更を防ぎますか?

引数として多数のファイルやディレクトリを使用する単純なbash関数を作成しようとしています。すべきこと:

  1. ファイル名を完全に修飾します。
  2. 並べ替えます。
  3. 重複を削除します。
  4. 実際に存在するものをすべて印刷します。
  5. 存在しないファイルの数を返します。

私はほとんど私が望むことをするスクリプトを持っていますが、ソートに失敗します。現状のスクリプトの戻り値は正しいですが、出力は正しくありません(ソートされておらず、重複しています)。 | sort -u 示されているステートメントでは、出力は正しいですが、戻り値は常にです。 。

N.B.問題を解決するためのより簡単な解決策は歓迎されますが、問題は本当にこれが私が持っているコードで発生する理由についてです。つまり、パイプを追加すると、スクリプトが変数rをインクリメントするのを停止するように見えるのはなぜですか。 ?

スクリプトは次のとおりです:

function uniqfile
{
    local r=0 

    for arg in "[email protected]"
    do  
        readlink -e "$arg" || (( ++r ))

    done #| sort -u    ## remove that comment

    return $r
}

承認された回答:

この機能が原因で、これはよく知られているバッシュの落とし穴です。 :

パイプラインの各コマンドは、個別のプロセスとして(つまり、サブシェルで)実行されます。

変更された変数がサブシェルに対してローカルであり、親に戻ると表示されないようにします。

これを回避するには、プロセス置換を使用して、パイプラインを回避するようにコードを言い換えます。

 for arg in "[email protected]"
    do  
        readlink -e "$arg" || (( ++r ))

    done > >(sort -u)

Linux
  1. フィールドの数値に基づいてファイルをソートする方法は?

  2. 一致しない場合の sed の戻りコード

  3. コマンドと出力の異なる色

  1. Linuxコマンドの出力を変数に割り当てる方法

  2. BashForループガイドと例

  3. この出力をソートする方法 1,10,11..2

  1. Du出力をサイズで並べ替える方法は?

  2. コマンドの出力をシェル変数に保存しますか?

  3. Bash Forループを並列化しますか?