以下を理解しているので質問があります。
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
と構文を混同しているようですwhile
。for
リストの各要素に対して一連のコマンドを実行します。構文は次のとおりです。キーワードは、値のリストから変数名を区切ります。他のコマンドシーケンスが真のときにコマンドシーケンスを実行します。for VARIABLE in VALUES; do COMMANDS; done
in
while
while COMMANDS; do COMMANDS; done
このコマンドはread
1行を読み取り、それをフィールドに分割します。パラメータread
はフィールド値を設定する変数です。したがって、最初のフィールドと2番目のフィールドにread in USUARIO
設定するか、フィールドが2つ以上の場合(シナリオの場合)、残りのすべてのフィールド(内部区切り文字を含む)に設定します。各呼び出しは 1 つの行を読み取るため、各ループ反復は 1 つの入力行を処理します。in
USUARIO
USUARIO
read
したがって、作成する必要があるユーザー名のみを印刷するには
while IFS=: read USUARIO rest
do
echo "$USUARIO"
done
2番目の質問(ただし、次回は関係のない質問を一緒に尋ねないでください)に関して、問題は、パイプラインの各コマンドがサブシェルで実行されるため、いずれかのコマンドで設定された変数がパイプラインの外に表示されないことです。バラより私の変数が「読んでいる間」ループにローカルであり、見かけに似た他のループではないのはなぜですか?