マシン上のすべてのユーザーdirsを一覧表示します。通常は、次のようにします。
ls -l /home
しかし、私はそれを他のマシンにデプロイされるスクリプトで使用し、おそらくそのマシンではホームと呼ばない(myHomeなど)。それで、それをls -l ~
に一般化したいと思います。しかし、すべてのユーザーのホームディレクトリ名ではなく、ユーザーのホームディレクトリを一覧表示するだけです(基本的に、マシン上のユーザー名のリストを取得したい)。どうすれば一般化できますか?
多くのシステムには、getent
、passwd
、group
、services
...などのName Serviceデータベースの内容を一覧表示またはクエリするprotocols
コマンドがあります。
getent passwd | cut -d: -f6
ホームディレクトリをリストします(6番目 コロンで区切られたフィールド)列挙可能なデータベース内のすべてのユーザーの。
ユーザー名自体は最初のフィールドにあるので、ユーザー名のリストの場合:
getent passwd | cut -d: -f1
(これらのユーザーがシステムにログインできる、またはホームディレクトリが作成されたことを意味するのではなく、システムに認識されていること、ユーザーIDに変換できることに注意してください)。
列挙できないデータベースの場合は、可能な各ユーザーIDを個別に試してクエリできます。
getent passwd {0..65535} | cut -d: -f1,6
(ここでは、uidが65535(一部のシステムはそれ以上をサポート)で停止し、zshの{x..y}
形式のブレース展開をサポートするシェルを想定しています)。しかし、LDAP、NIS +、SQLなどのユーザーデータベースがネットワークで接続されている(ローカルキャッシュが制限されている)システムでは、これを頻繁に実行することは望ましくありません。 )これらすべてのクエリを実行します。
つまり、同じuidを共有している複数のユーザーがいる場合、各uidに対して1つのエントリしか取得できないため、他のユーザーを逃すことになります。
getent
がない場合は、Perl
を使用することができます。
Perl -le 'while (@e = getpwent) {print $e[7]}'
getent passwd
(ユーザー名は$e[0]
)、または:
Perl -le 'for ($i=0;$i<65536;++$i) {
if (@e = getpwuid $i) {print $e[0] ": " $e[7]}}'
同じ警告を持つgetent passwd {0..65535}
の場合。
シェルでは、~user
を使用してuser
のホームディレクトリを取得できますが、ほとんどのシェルでは、限られたユーザー名のセットに対してのみ機能します(その~
拡張演算子でサポートされるユーザー名で許可される文字のリストは、シェルによって異なります)およびいくつかのシェル(bash
を含む)では、~$user
は機能しません(ユーザーの名前が変数に格納されている場合は、eval
を使用する必要があります)。また、ユーザー名のリストを取得する方法を見つける必要があります。
一部のシェルには、そのユーザー名のリストを取得するための組み込みサポートがあります。
bash
:compgen -u
は、列挙可能なデータベース内のユーザーのリストを返します。zsh
:連想配列$userdirs
は、ユーザー名をホームディレクトリにマップします(列挙可能なデータベースに限定されますが、列挙不可能なデータベースにあるユーザーに対して~user
拡張を行うと、$userdirs
にエントリが追加されます)。 。だからあなたはできる:
printf '%s => %s\n' "${(kv@)userdirs}"
ユーザーをホームディレクトリにリストします。
tcsh
、fish
、およびyash
は、ユーザー名を完成できる他の3つのシェルです(たとえば、~<Tab>
引数を完成させる場合など)が、プログラムでユーザー名のリストを取得できるようには見えません。
ユーザーのホームディレクトリを一覧表示するより良い方法は、_/etc/passwd
_を解析してそこから抽出することです。
そして、2番目のコメントから判断すると、実際にはホームディレクトリではなくユーザー名が必要です。この場合、いずれにしても_/etc/passwd
_の方が適しています。一部のLinux/UNIXマシンでは、他のユーザー認証メカニズム(LDAPなど)が構成されているため、結局のところ、クエリは最初に想像するよりも複雑ですが、_/etc/passwd
_から始めるとよいでしょう。
短い答え:
compgen -u
中程度の回答:bash
を使用しているので、~
を使用して、compgen -A user
に対して可能なすべての補完をリストできます。これは、このような一般的な使用法であり、compgen -u
と省略できます。ビルトインシェルとして、compgen
には独自のmanページがありません。代わりに、bash(1)のドキュメントを参照し、Programmable Completion。
より完全な代替手段
移植性について非常に心配している場合は、bash
を備えた他のマシンに依存することさえできないかもしれません。その場合は、次のようにします。
(getent passwd ||
dscl . -ls /Users dsAttrTypeNative:homeDirectory ||
nidump passwd ||
cat /etc/passwd) 2>/dev/null | cut -d: -f6
説明長い答えはすべてを試すので、新しい/etc/nsswitch.confを使用しているかどうかに関係なく、ほとんどのUNIXシステムで動作します(GNU/LinuxとBSDの両方にgetent
)、従来のUNIX passwdフラットファイル、MacOSのディレクトリサービス¹(dscl
)、または古い、猫をテーマにしたMacOS XリリースとNeXTSTEP(nidump
)。
シンプルさしかし、どの程度の移植性が必要ですか? Unixには多くの方法があり、場合によってはより単純なもので十分です。選択する必要がある場合は、シェルスクリプト用にgetent passwd | cut -d: -f6
をお勧めします。²
脚注¹:私はMacOSを少し使用していませんので、誰かが私に構文が正しいことを確認できれば(そして出力には混乱を招く迷子のコロンが含まれていません) cut
)、それは素晴らしいでしょう。よろしくお願いします。
脚注²:私が推奨することと実行することは異なる場合があります。個人的には、コマンドラインで従来のcut -d: -f1 /etc/passwd
をより頻繁に使用します。数十年の繰り返しの後、私の心が他のことに取り組んでいる間、私の指はそれをタイプすることができます。
ls -l ~/..
?これにより、ホームディレクトリの親にあるすべてのディレクトリが一覧表示されます。