1

POSIXPerl でグループのすべてのメンバーのリストを取得する方法はありますか?

getgrent()スペースで区切られた文字列としてリストを返し、一部のユーザー名にはスペースが含まれている可能性があるため、and similarは使用できません。

他の組織がユーザーとグループを作成できる AD 環境で作業しているため、ユーザー名とグループ名のスペースを処理する必要があります。

4

2 に答える 2

1

getgrent()スペースを気にせずに使うだけだと思います。

おそらく手動で編集することにより、1 つ以上のスペースを含むユーザー名を作成することは可能かもしれませんが、/etc/passwd他の問題も引き起こします。たとえば、~foofooのホーム ディレクトリですが、 のホーム ディレクトリで~foo barはありませんfoo bar

Linux では、コマンドuseraddadduserコマンドでファイル名にスペースを使用することさえできません。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ことができます。

  • su - 「フーバー」
  • ssh 'foo bar@localhost'

などしかし、それは本当に悪い考えです。Perlは、グループに and のエントリが 1 つ含まれているのか、 andのエントリが 2 つgetgr*()含まれているのかを判断できません(これがあなたの質問です)。また、シェルの構文を使用してアカウントのホーム ディレクトリを参照することもできません。他の方法を使用して両方の情報を取得することもできますが、そもそもそのようなアカウントを作成しないようにする方がはるかに簡単です。foo barfoobar~name

そのようなアカウントを作成するほど愚かな管理者がいることを真剣に心配している場合は、議論されている代替方法のいくつかを使用できます. しかし、私が言ったように、私はそれが努力の価値があるとは思わない.

:(Perlは、スペースではなく文字でリストを区切ることによって、この問題を回避できたはずです。スペースは、システムが依存している/etc/passwdandのフォーマットと実際には互換性がないためです/etc/group。しかし、今それを変更するには遅すぎます。)

更新 2:

あなたがコメントで言うように(私はあなたの質問に編集しました):

他の組織がユーザーとグループを作成できる AD 環境で作業しているため、ユーザー名とグループ名のスペースを処理する必要があります。

同じコメントからのソリューション:

map((getgrgrid($_))[0], split(/ /, `id -G $username`))

おそらく最善の回避策です。(id -G数値のグループ ID を出力します。明らかにスペースを含めることはできません。)

実際にユーザー名またはグループ名にスペースが含まれているかどうかを確認することもおそらく価値があります (もちろん、将来そのような名前が追加されることを防ぐわけではありません)。あなたのPOSIXシステムは実際にそのような名前をどのように扱っているのだろうか. それらが何らかの方法で自動的に翻訳されていても、私は驚かないでしょう. それでも、id -Gソリューションは引き続き機能します。

于 2013-01-09T07:42:43.940 に答える
0

私が持っている場合/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

資力

于 2013-01-09T06:02:41.810 に答える