我有疑问,因为我明白:
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”循环,而不是另一个看似类似的循环?