#!/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[*]}"
if I execute above with ksh
replacing sebang
it works, but with bash it does not.
#!/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[*]}"
if I execute above with ksh
replacing sebang
it works, but with bash it does not.
Both sh and bash create a subshell after the pipe.
In other words, while block inherits the variables from the parent shell but modification won't affect the variables in the parent shell.
ksh is not creating a subshell, so it is working.
In my tests, the script provided does not run in pure sh.
A simple sh solution would be to use /etc/passwd directly:
#!/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}
There is below a solution using bash (with @pjh hint):
#!/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[*]}
In order to illustrate this subshell situation, the version below prints all the users, but still the values of the variables are unchanged in parent shell (with @glennjackman hint):
#!/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[*]}
)