POSIX
Perl でグループのすべてのメンバーのリストを取得する方法はありますか?
getgrent()
スペースで区切られた文字列としてリストを返し、一部のユーザー名にはスペースが含まれている可能性があるため、and similarは使用できません。
他の組織がユーザーとグループを作成できる AD 環境で作業しているため、ユーザー名とグループ名のスペースを処理する必要があります。
POSIX
Perl でグループのすべてのメンバーのリストを取得する方法はありますか?
getgrent()
スペースで区切られた文字列としてリストを返し、一部のユーザー名にはスペースが含まれている可能性があるため、and similarは使用できません。
他の組織がユーザーとグループを作成できる AD 環境で作業しているため、ユーザー名とグループ名のスペースを処理する必要があります。
getgrent()
スペースを気にせずに使うだけだと思います。
おそらく手動で編集することにより、1 つ以上のスペースを含むユーザー名を作成することは可能かもしれませんが、/etc/passwd
他の問題も引き起こします。たとえば、~foo
はfoo
のホーム ディレクトリですが、 のホーム ディレクトリで~foo bar
はありませんfoo bar
。
Linux では、コマンドuseradd
とadduser
コマンドでファイル名にスペースを使用することさえできません。Linux Mint 14 (Ubuntu 12.10 ベース) の場合:
$ sudo adduser 'foo bar'
adduser: To avoid problems, the username should consist only of
letters, digits, underscores, periods, at signs and dashes, and not start with
a dash (as defined by IEEE Std 1003.1-2001). For compatibility with Samba
machine accounts $ is also supported at the end of the username
$ sudo useradd !$
sudo useradd 'foo bar'
useradd: invalid user name 'foo bar'
$
システムにスペースを含むユーザー名が実際にありますか?
更新:スペースを含むユーザー名を実際に作成できることがわかりました。useradd
許可しadduser
ないでください(新しいアカウントを作成するには、これらのコマンドのいずれか、または同様のものを使用する必要があります)。/etc/passwd
しかし、 を使用して手動で編集するsudo vipw
と、 という名前のユーザーを作成でき、次のfoo bar
ことができます。
などしかし、それは本当に悪い考えです。Perlは、グループに and のエントリが 1 つ含まれているのか、 andのエントリが 2 つgetgr*()
含まれているのかを判断できません(これがあなたの質問です)。また、シェルの構文を使用してアカウントのホーム ディレクトリを参照することもできません。他の方法を使用して両方の情報を取得することもできますが、そもそもそのようなアカウントを作成しないようにする方がはるかに簡単です。foo bar
foo
bar
~name
そのようなアカウントを作成するほど愚かな管理者がいることを真剣に心配している場合は、議論されている代替方法のいくつかを使用できます. しかし、私が言ったように、私はそれが努力の価値があるとは思わない.
:
(Perlは、スペースではなく文字でリストを区切ることによって、この問題を回避できたはずです。スペースは、システムが依存している/etc/passwd
andのフォーマットと実際には互換性がないためです/etc/group
。しかし、今それを変更するには遅すぎます。)
更新 2:
あなたがコメントで言うように(私はあなたの質問に編集しました):
他の組織がユーザーとグループを作成できる AD 環境で作業しているため、ユーザー名とグループ名のスペースを処理する必要があります。
同じコメントからのソリューション:
map((getgrgrid($_))[0], split(/ /, `id -G $username`))
おそらく最善の回避策です。(id -G
数値のグループ ID を出力します。明らかにスペースを含めることはできません。)
実際にユーザー名またはグループ名にスペースが含まれているかどうかを確認することもおそらく価値があります (もちろん、将来そのような名前が追加されることを防ぐわけではありません)。あなたのPOSIXシステムは実際にそのような名前をどのように扱っているのだろうか. それらが何らかの方法で自動的に翻訳されていても、私は驚かないでしょう. それでも、id -G
ソリューションは引き続き機能します。
私が持っている場合/etc/group
:
...
postgres:x:26:
fsniper:x:481:
clamupdate:x:480:
some spacey group:x:482:saml, some spacey user
次のコマンドを使用して、このグループのメンバーを確認できます。
% getent group
...
postgres:x:26:
fsniper:x:481:
clamupdate:x:480:
some spacey group:x:482:saml,some spacey user
または、関心のある特定のグループを知っている場合:
% getent group "some spacey group"
some spacey group:x:482:saml,some spacey user
これらは、次のように Perl スクリプト内にラップできます。
#!/usr/bin/perl
use feature qw(say);
chomp (my $getent = `getent group "some spacey group" | sed 's/.*://'`);
my @users = split(/,/, $getent);
foreach my $i (@users) { say $i; }
それを実行する:
% ./b.pl
saml
some spacey user