#!/bin/sh
NR=0
getent passwd | while IFS=':' read USERNAME PSSWD MY_UID MYGID GECOS HOMEDIRS SHELLS
do
users[$NR]=$USERNAME
((NR++))
done
echo "${users[*]}"
如果我执行上面ksh
替换sebang
它可以正常工作,但是使用bash却不行。
答案 0 :(得分:1)
sh 和 bash 都会在管道后创建子shell。
换句话说,而块从父shell继承变量,但修改不会影响父shell中的变量。
ksh 没有创建子shell,因此它正在运行。
在我的测试中,提供的脚本不能以纯 sh 运行。
一个简单的 sh 解决方案是直接使用 / etc / passwd :
#!/bin/sh --
NR=0
users=""
while IFS=':' read USERNAME PSSWD MY_UID MYGID GECOS HOMEDIRS SHELLS ; do
users="${users} ${USERNAME}"
NR=$(expr "${NR}" + 1)
done < /etc/passwd
printf "%s\n" ${users}
下面有一个使用bash的解决方案(使用@pjh提示):
#!/bin/bash --
NR=0
passwdentries="$(getent passwd)"
if [ $? -ne 0 ] ; then
exit 1
fi
while IFS=':' read USERNAME PSSWD MY_UID MYGID GECOS HOMEDIRS SHELLS ; do
users[$NR]=$USERNAME
((NR++))
done <<<"${passwdentries}"
printf "%s\n" ${users[*]}
为了说明这个子shell情况,下面的版本打印了所有用户,但是在父shell中变量的值仍未改变(使用@glennjackman提示):
#!/bin/bash --
NR=0
getent passwd | (
while IFS=':' read USERNAME PSSWD MY_UID MYGID GECOS HOMEDIRS SHELLS ; do
users[$NR]=$USERNAME
((NR++))
done
printf "%s\n" ${users[*]}
)