次のコードを使用してファイルを配列に読み込もうとしています。
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でのみこれを行うことが最悪の方法の1つであると提案したいと思います。
また、/etc/group
ファイルはグループデータの可能なソースの1つにすぎないため、読み込み自体は良い考えではありません。他のソースには、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やkshなどの他のシェルで作業するのと同義ですtypeset
。declare