すべてのユーザー名やホームディレクトリをリストするにはどうすればよいですか?


16

マシン上のすべてのユーザーを一覧表示したいのですが、通常は次のようにします:

ls -l /home

しかし、私は他のマシンに展開されるスクリプトでそれを使用します。おそらく、彼らはそれを自宅とは呼ばないマシン(例えばmyHome)にデプロイします。だから私はそれを一般化したいls -l ~。しかし、それはすべてのユーザーのホームディレクトリの名前ではなく、私のユーザーのホームディレクトリをリストするだけです(基本的にはマシン上のユーザー名のリストを取得したいです)。どのように一般化できますか?


19
実際にはあり、全てのユーザのホームディレクトリは、サブディレクトリのあることを保証なしの任意のディレクトリ。
ホッブズ

17
@hobbsまたはユーザーがログインするまで存在していること。これは、明らかに簡単な問題の1つであり、非常に迅速に複雑になります。
EightBitTony

11
心に留めておく~一般的であるのと同等/home/userではないの、/homeまたは/home/*(より近いあなたの意図にあるように思われます)。
イーサンカミンスキー

2
@EightBitTony:...もホームディレクトリが存在するという保証があり、すべてでは。たとえば、私のUbuntuのインストールでは、いくつかのシステムユーザー(を含むnobody)のホームディレクトリがに設定されていますが/nonexistent、これは明らかに存在しません。(もちろん、これらのユーザーのパスワードハッシュはに設定され*、シェルは/usr/sbin/nologinまたは/bin/falseに設定されているため、最初から通常の意味でログインすることはできません。)
Ilmari Karonen

1
一方、(古い学校の)NFSサーバーは、OSに名前で知られていないユーザーのホームディレクトリを提供する場合があります。
rackandboneman

回答:


45

多くのシステムが持っているgetentリストまたはクエリの内容にコマンドをネームサービスなどのデータベースpasswdgroupservicesprotocols...

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]}'

for 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ユーザーの名前がそこの変数に格納されている場合に頼る必要があります)。また、ユーザー名のリストを取得する方法を見つける必要があります。

一部のシェルには、ユーザー名のリストを取得するためのサポートが組み込まれています。

  • bashcompgen -u列挙可能なデータベース内のユーザーのリストを返します。
  • zsh$userdirs連想配列は、ユーザー名をホームディレクトリにマップします(列挙可能なデータベースに限定されますが、列挙~user不可能なデータベースにいるユーザーに対して拡張を行うと、エントリがに追加されます$userdirs)。だからあなたができる:

    printf '%s => %s\n' "${(kv@)userdirs}"

    ユーザーをホームディレクトリとともに一覧表示します。

    zshただし、インタラクティブな場合にのみ機能します

  • tcshfishおよびyashは、ユーザー名を補完できる他の3つのシェルです(たとえば、~<Tab>引数を補完する場合)が、プログラムでユーザー名のリストを取得できるようには見えません。


OPにとっての課題は、getentそこに行くかどうかを知ることです。これは、ある程度は「他のマシン」の範囲に依存すると思います。
EightBitTony

1
@EightBitTony、perl代替手段を追加しました。
ステファンシャゼル

1
Macでは、おそらくOpen Directoryに関係するものです。
SilverWolf-モニカの復活

@ seaturtle、perl -le 'while (@e = getpwent) {print $e[7]}'macOSで正常に動作します。
ステファンシャゼル

1
@FloHe、これらはユーザー名です。Unixシステムのほとんどのユーザーは、システムサービスの実行に専念する特別なシステムユーザーです。getent passwdユーザーデータベースを表示します。最初のフィールドはユーザー名で、6番目のフィールドはユーザーのホームディレクトリです。
ステファンシャゼル

17

ユーザーのホームディレクトリをリストするより良い方法は、解析することです /etc/passwd、そこからそれらして抽出することであり、それらがどこにあるかについての仮定をしないことです。

そして、2番目のコメントから判断すると、実際にはホームディレクトリではなくユーザー名/etc/passwdが必要です。その場合、いずれにしても良い選択です。一部のLinux / UNIXマシンには他のユーザー認証メカニズム(LDAPなど)が構成されているため、最終的に、クエリは最初に想像するよりも複雑ですが/etc/passwd、開始するのに適していることに注意してください。


9
getentそれをサポートするシステムも参照してください。
クサラナナンダ

6
はい、getent解析よりも常に優れています/etc/passwd(「他のユーザー認証メカニズム」に関する懸念に対処します)。
スティーブンキット

@Kusalanandaソリューションの問題getentは、特定の値を照会するだけでなく、データソースを列挙できることを前提としていることです。詳細については、この質問に対するステファンチャゼラスの回答をご覧ください。
アンドリューヘンレ

7

短い答え

compgen -u

中程度の答え:使用しているのでbash~使用可能なすべての補完をリストできますcompgen -A user。これは非常に一般的な使用法であり、省略できますcompgen -u。シェルビルトインとして、compgen独自のマニュアルページはありません。代わりに、ドキュメントについては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(GNU / LinuxとBSDの両方に付属getent)、従来のUNIX passwdフラットファイル、MacOSのいずれを使用するかに関係なく、ほとんどすべてのUNIXシステムで動作しますディレクトリサービス¹(dscl)、または古い、猫をテーマにしたMacOS XリリースとNeXTSTEP(nidump)も。

シンプルさ しかし、どの程度ポータブルである必要がありますか?Unixにはさまざまな方法があり、場合によってはそれで十分です。いずれかを選択する必要がある場合はgetent passwd | cut -d: -f6、シェルスクリプトをお勧めします。²


脚注¹:MacOSを少し使用したことがないので、構文が正しいことを誰かが確認してくれれば(そして出力に混乱するようなコロンが含まれていない場合cut)、それは素晴らしいことです。ありがとう。

脚注²:推奨事項と実行内容は異なる場合があります。個人的にcut -d: -f1 /etc/passwdは、コマンドラインで従来の方法をより頻繁に使用します。数十年の繰り返しの後、私の心が他のことに取り組んでいる間、私の指はそれをタイプできます。


2
すべてのMac OS Xマシンは、システムに付属しているため、bashが保証されています。(zshおよび他のいくつかのシェルも同様です。)
SilverWolf-モニカを復活させる

確かに、MacOSを使用していた頃は、Appleは長い間bashを更新していませんでしたが、バージョン3の無愛想なものを常に交換しなければなりませんでした。Appleはbashの更新について改善しましたか?
hackerb9


確かに、それについては考えませんでした。bash(macOS Sierra 10.12.6)の私のバージョンは3.2.57です。(:
SilverWolf-モニカの復元

とにかく、2000年に2.04がリリースされbashcompgen -uからです。
StéphaneChazelas 17

2

どうls -l ~/..?これにより、ホームディレクトリの親にあるすべてのディレクトリが一覧表示されます。


4
これは、すべてのホームディレクトリが同じディレクトリに基づいているシステムでのみ機能します。これは多くありません(/homeLinuxシステムでは一般的と思われるかもしれませんが、それを実行するとrootどうなりますか?)。ホームディレクトリのリストは、遭遇する可能性のあるすべてのケースを処理する場合の落とし穴に満ちた冒険です。詳細については、他の回答を参照してください。
スティーブンキット

7
これは間違いなく、直接OPの答え今のところ唯一の答えである、知覚の問題を。ただし、OPの根本的な問題には答えません。
パイプ

1
この回答の価値は、見逃しているものを理解することであり、なぜ他の上位投票の回答ほど良くないのかを理解することです。
クリギー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.