我有疑問,因為我明白:
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
您似乎混淆了for
and的語法while
。for
對清單中的每個元素執行一系列命令;語法是:關鍵字將變數名稱與值清單分開。當另一個命令序列為真時執行一個命令序列;語法是.for VARIABLE in VALUES; do COMMANDS; done
in
while
while 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」循環,而不是另一個看似類似的循環?