You already have an answer saying how to do this entirely in bash with a while ... read ...
loop...I'd like to suggest that doing it in bash alone is one of the worst ways to do this.
Also, reading /etc/group
itself is not a good idea because that file is just one of the possible sources of group data (other sources may include LDAP, Active Directory, winbind, NIS, mysql, pgsql, Berkeley db files, extra group files from libnss-extrausers
, and many more).
Instead, use the output of getent group
.
Try this:
g=( $(getent group | awk -F: '{print $3}') )
or
g=( $(getent group | cut -d: -f3) )
The awk
method is particularly useful if you want to combine it with regexp or fixed-text search and/or other selection criteria (e.g. $1 == groupname
or $3 >= 500 && $3 <= 1000
)
BTW for, e.g., debugging you can print the groups in array g
with, e.g.:
# all on one line
echo "${g[@]}"
# one element per line
printf "%s\n" "${g[@]}"
# in a format that can be re-used to define the variable in another
# bash shell or script.
declare -p g
I particularly like declare -p
for debugging - it not only shows you the variable name (e.g. similar to echo "foo='$foo'"
), it also shows the array indices for array variables, and everything is properly quoted and backslash-escaped:
$ g=( $(getent group | awk -F: '$1 ~ /my/ {print $1}') )
$ declare -p g
declare -a g='([0]="mysql" [1]="mythtv")'
BTW typeset
is a synonym for declare
that works in bash and also some other shells like ksh.