使用read、IFS和while一起的疑惑

使用read、IFS和while一起的疑惑

我有疑問,因為我明白:

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

輸出應該是包含所有系統使用者的列表,而不是當我想要第一行時,我會得到第二行,其中填充了 x;為什麼?

此外,在此腳本中,您傳遞一個數字作為參數,您會看到擁有與輸入值相同且更多檔案的使用者清單:

#!/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

您似乎混淆了forand的語法whilefor對清單中的每個元素執行一系列命令;語法是:關鍵字將變數名稱與值清單分開。當另一個命令序列為真時執行一個命令序列;語法是.for VARIABLE in VALUES; do COMMANDS; doneinwhilewhile COMMANDS; do COMMANDS; done

該命令read讀取一行並將其拆分為多個欄位。的參數read是要設定字段值的變數。因此,read in USUARIO設定in為第一個字段和USUARIO第二個字段,或者如果有兩個以上字段(您的場景中就是這種情況),則USUARIO設定為所有剩餘字段(包括內部分隔符)。每次呼叫都會read讀取一行,因此每次循環迭代都會處理一行輸入。

因此,要僅列印用戶名,您需要編寫

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

關於第二個問題(但下次請不要一起問不相關的問題),問題是管道中的每個命令都是在子shell中執行的,因此其中一個命令中設定的變數在管道外部不可見。看為什麼我的變數是本地一個「while read」循環,而不是另一個看似類似的循環?

相關內容