使用以下代码,我尝试将文件读入数组:
GROUPS=()
while IFS=: read -r g1 g2 g3 g4
do
GROUPS+=("$g3")
echo "$g3"
done < /etc/group
这不起作用,它甚至不输出任何内容,但是,如果我只留下回显,它会打印文件的内容。只要添加到数组的指令出现在循环中的某个位置,就不会打印任何内容。这看起来很奇怪,因为我可以毫无问题地对其他文件执行此操作。
知道是什么原因造成的吗?我用 bash -x 检查过,当存在有问题的指令时,它甚至不会进入循环。
另外,如果相关的话,我会以 root 身份运行它。
答案1
您不幸地选择了数组的名称,该名称已由bash
自身保留,并且是只读,所以你无法更改它。
团体
包含当前用户所属组列表的数组变量。对 GROUPS 的分配无效并返回错误状态。如果 GROUPS 未设置,它将失去其特殊属性,即使随后重置也是如此。
只需使用另一个名称,代码就应该可以工作。
答案2
您已经有了一个答案,说明如何完全在 bash 中使用循环执行此操作while ... read ...
...我想建议单独在 bash 中执行此操作是最糟糕的方法之一。
另外,读取/etc/group
本身并不是一个好主意,因为该文件只是组数据的可能来源之一(其他来源可能包括 LDAP、Active Directory、winbind、NIS、mysql、pgsql、Berkeley db 文件、来自 的额外组文件libnss-extrausers
,以及还有很多)。
相反,使用 的输出getent group
。
尝试这个:
g=( $(getent group | awk -F: '{print $3}') )
或者
g=( $(getent group | cut -d: -f3) )
awk
如果您想将其与正则表达式或固定文本搜索和/或其他选择标准(例如$1 == groupname
或$3 >= 500 && $3 <= 1000
)结合使用,该方法特别有用
顺便说一句,例如,为了调试,您可以打印数组中的组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
我特别喜欢declare -p
调试 - 它不仅显示变量名称(例如类似于echo "foo='$foo'"
),还显示数组变量的数组索引,并且所有内容都正确引用并反斜杠转义:
$ g=( $(getent group | awk -F: '$1 ~ /my/ {print $1}') )
$ declare -p g
declare -a g='([0]="mysql" [1]="mythtv")'
BTW是bash 和其他一些 shell(如 ksh)中工作typeset
的同义词。declare