仅当不使用数组时,使用 IFS 循环读取文件才有效

仅当不使用数组时,使用 IFS 循环读取文件才有效

使用以下代码,我尝试将文件读入数组:

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

相关内容