読取り、IFS、while を一緒に使用することについての疑問

読取り、IFS、while を一緒に使用することについての疑問

以下を理解しているので質問があります。

exec 0</etc/passwd
IFS=:
while read in USUARIO
do
    echo $USUARIO
done

出力は、すべてのシステムユーザーを含むリストでなければなりません。代わりに、最初の行が必要なときにxが埋められた2番目の行を取得するのはなぜですか?

このスクリプトでは、数値を引数として渡し、入力した値と同じで、より多くのファイルを持つユーザーのリストを表示できます。

#!/bin/bash

if [[ ( $# -eq 1) && ( $1==[0-9][0-9]* )]]
then
    echo "User with $1 files or more "
    cut -d':' -f1 /etc/passwd | while IFS= read -r USUARIO
    do
        if [[ $( find / -user $USUARIO -print | wc -l ) -ge $1 ]]
        then

            echo $USUARIO
        fi
    done
exit 0
else
    printf "Error: $0 int"
    exit 1
fi

うまくいきますが、うまくいかない理由は次のとおりです。

#!/bin/bash

if [[ ( $# -eq 1) && ( $1==[0-9][0-9]* )]]
then
    LIST="Users with more or $1 files: "
    cut -d':' -f1 /etc/passwd | while IFS= read -r USUARIO
    do
        if [[ $( find / -user $USUARIO -print | wc -l ) -ge $1 ]]
        then

            LIST="$LIST $USUARIO"
        fi
    done
echo $LIST
exit 0
else
    printf "Error $0 int"
    exit 1
fi

出力は、ユーザー名が追加されていない生の文字列です。なぜですか?

答え1

forと構文を混同しているようですwhileforリストの各要素に対して一連のコマンドを実行します。構文は次のとおりです。キーワードは、値のリストから変数名を区切ります。他のコマンドシーケンスが真のときにコマンドシーケンスを実行します。for VARIABLE in VALUES; do COMMANDS; doneinwhilewhile COMMANDS; do COMMANDS; done

このコマンドはread1行を読み取り、それをフィールドに分割します。パラメータreadはフィールド値を設定する変数です。したがって、最初のフィールドと2番目のフィールドにread in USUARIO設定するか、フィールドが2つ以上の場合(シナリオの場合)、残りのすべてのフィールド(内部区切り文字を含む)に設定します。各呼び出しは 1 つの行を読み取るため、各ループ反復は 1 つの入力行を処理します。inUSUARIOUSUARIOread

したがって、作成する必要があるユーザー名のみを印刷するには

while IFS=: read USUARIO rest
do
    echo "$USUARIO"
done

2番目の質問(ただし、次回は関係のない質問を一緒に尋ねないでください)に関して、問題は、パイプラインの各コマンドがサブシェルで実行されるため、いずれかのコマンドで設定された変数がパイプラインの外に表示されないことです。バラより私の変数が「読んでいる間」ループにローカルであり、見かけに似た他のループではないのはなぜですか?

関連情報