すべての人間のユーザーをリストする


19

作成したすべての人間のユーザーを一覧表示するにはどうすればよいですか?私は試しましたがcat /etc/passwd、それはただたくさんのものをリストしています。

回答:


18

人間のユーザーのUIDは1000から始まるため、その事実を使用して人間以外のユーザーを除外できます。

cut -d: -f1,3 /etc/passwd | egrep ':[0-9]{4}$' | cut -d: -f1

これにより、最初の(ユーザー名)および3番目(UID)のコロンで区切られたフィールドがから/etc/passwd切り取られ、コロンと4桁で終わる結果の行がフィルター処理されます。次に、最初の(ユーザー名)フィールドが切り取られ、 UIDが1000〜9999のユーザー。

システムに9000人を超えるユーザーがいる場合、これは失敗しますが、キャッチしないように結果を4桁のUIDに制限する必要がありますnobody(UID 65534)。


15

これは、3つのコマンドではなく1つのコマンドで、受け入れられた答えが行うこととほぼ同じです。

awk -F: '$3 >= 1000 && $1 != "nobody" {print $1}' /etc/passwd

また、コメントのKarelのおかげで、nobodyユーザーも除外されています。


@karelええ、多分。UIDでフィルタリングする代わりに、そのユーザー名を明示的にフィルタリングしています。高いUIDを持つ正当なユーザーがいる理由があるかもしれません...誰が知っている;)
オリ

9

私は個人的にちょうど使用したい:

ls /home

確かに、これはユーザーのリストではなく、ホームディレクトリのリストです。現在、システムに存在する人間のユーザー/homeのホームディレクトリはにありますが、削除された過去のユーザーのホームディレクトリも表示される場合があります。

これは私の目的のために機能し、あなたのものにも機能する可能性があります。たとえば、存在しないことが判明したユーザーアカウント(nonexistent-user)を削除してコマンドを実行する場合

sudo deluser nonexistent-user

このユーザーが存在しないことがわかります。


+1この方法は簡単です。これは、ほとんどの経験豊富なユーザーが実際に行うことであり、UIDの範囲をチェックする方法と同じくらい堅牢であると思います。人間のユーザーが1000未満のUIDを持っているよりも、外部に/home(シンボリックリンクされていない/home)ホームディレクトリを持っている可能性は低いようです(結局、これはディスプレイマネージャーがリストに表示されないようにする最も一般的な方法です)ログイン画面のユーザー。これは、人間のユーザーに対して行われる場合があります)。ここでの1つの比較的小さな欠点は、lost+found個別の/homeパーティションを持つシステムにリストされることです。
エリアケイガン

ただし、小さな問題:ユーザーがで作成された場合はどうなりますuseradd --no-create-home usernameか?
セルギーKolodyazhnyy

@Serg問題の説明に内在するあいまいさが原因だと思います。ホームディレクトリのないアカウントは実際に人間のユーザーを表しますか?実際には、そのようなアカウントは通常-常にではありませんが-非常に特殊なタスク(通常は独自の個別のアカウントを持つ人々)または特定の制限されたサービスを通じてのみシステムにアクセスするユーザーに使用されます。もちろん、別の使用例がありますuseradd --no-create-home-ホームディレクトリが既に存在するか、またはその後すぐに作成される可能性があります-しかし、ls /homeメソッドはそれらの場合にうまく機能します。
エリアケイガン

4

それは明確な考えのように見えるかもしれませんが、実際には人間のユーザーの意味にはあいまいさがあります。ユーザーアカウントは、特別な目的(ただし、人間)のみに使用されるため、ログイン画面から意図的に隠されていますか?ubuntuライブCD のユーザー(UID 999)はどうですか?また、Ubuntuのゲストアカウントはその場で作成され、ログアウト後に破棄されます。彼らは人間のユーザーですか?さらに多くの例を考案することができます。

したがって、同等ではない複数の回答が与えられたのは適切です。Saige Hamblinの実行ソリューションls /homeは、人々が実際に行うことであり、スクリプトを作成しているのでなければ、おそらくそれを使用するだけです。

作るls /homeより堅牢

ただし、削除されたユーザーがいる可能性がありますが、そのユーザーのホームディレクトリはまだに存在する/homeため、リストに表示しないようにする必要があります。または、他の何らかの理由で/home、実際のアカウントに対応するエントリのみがリストされていることを確認する必要があります。

その場合、私は中にすべての名前を渡すことをお勧め/homeするgetent(取得するために、passwdこれらの名前を持つユーザーのエントリを)、その後、分離株とディスプレイだけでユーザー名フィールド(とgrepsedまたはawk、あなたの好みによります)。これらのいずれかが行います:

getent passwd $(ls /home) | grep -o '^[^:]*'
getent passwd $(ls /home) | sed 's/:.*//'
getent passwd $(ls /home) | awk -F: '{print $1}'

名前に空白文字や制御文字を含むユーザーアカウントを使用しないようにしてください。Ubuntuを許可するように再構成しなければ、できません。もしそうなら、あなたはより大きな問題を抱えています。したがって、解析に関する通常の問題ls適用できません。しかし、ここでは本当に大丈夫ですが、ls審美的に不快な、または単に悪い習慣のコマンド置換を検討する場合、あなたは好むかもしれません:

getent passwd $(basename -a /home/*) | grep -o '^[^:]*'
getent passwd $(basename -a /home/*) | sed 's/:.*//'
getent passwd $(basename -a /home/*) | awk -F: '{print $1}'

これらは空白や制御文字にも対応していません。私が提供するの$(ls /home)は、それが正しい場合でも間違っているように見えるためであり、したがって多くのユーザーを間違った方法でこすります。ほとんどの状況では、解析を避ける本当の理由がlsあり、そのような状況でbasename -aは、解析は通常非常にわずかに悪いだけです。ただし、この状況では、ユーザー名実際に使用できる文字には制限があるため、どちらも問題ありません

説明、利点、欠点

getent主に使用するのは、出力を制限するための引数としてユーザー名を受け入れるためです。また、/etc/passwd認証機能とパスワードデータベースがネットワークサービスによって提供される場合、直接検査するよりも少し汎用的であるためです。

この方法には、ls /home別の/homeパーティションを持つシステムでは、lost+found通常の出力に表示されるという追加の利点がありls /homeます。

  • 上記のより堅牢な方法では、lost+foundが呼び出されるユーザー(人間かどうかに関係なく)が発生した場合にのみ表示されますlost+found
  • ただし、スクリプトを記述するのではなく、対話形式でコマンドを入力する場合ls /homeは問題ありません。人間のユーザーが呼び出されないことを知っていますlost+found

まれに、この方法(上記のバリエーションのいずれか)で不十分な出力が生成されることがあります。

  • ユーザーのホームディレクトリが外部/homeに存在する場合、またはまったく存在しない場合、これはアカウントが人間のユーザーを表すと見なされるべきではないことを示唆していますが、示唆するものではありません。このメソッドは、に同じ名前のディレクトリがある場合にのみユーザーをリストします/home
  • /home実際に誰のホームディレクトリでもない追加のディレクトリを作成しそれらがたまたま既存の非人間ユーザーと同じ名前を持っている場合、または空白で区切られた単語で構成されている場合、1つ以上が同じ名前を持っている既存の非人間ユーザーとして-それから、いくつかの非人間ユーザーが出力に含まれることがあります。
    (このメソッドはループと個別のgetent呼び出しで実装できるため、単語の分割は誤った出力を生成しません。しかし、複雑さは保証されません。基本的に、/homeユーザーのホームディレクトリ以外の場所として使用する場合、このメソッドは信頼できる出力を生成しません。)

UIDチェックを簡単にする

ユーザーIDをチェックして、受け入れられた回答Oliの回答のように人間を表すアカウントの可能性のある範囲にあることを確認する方法を採用する場合は、簡潔にするためにこれをお勧めします。

getent passwd | grep -oP '^[^:]+(?=:x:\d{4}:)'

これは、Perl正規表現-P)を使用して以下を表示します。

  • 行の先頭にテキスト(^全く含まない):、Sを([^:]+) -として、これは、最初のフィールドである:フィールドセパレータはありますpasswd
  • (?= )パスワードフィールドは先行しますが、パスワードフィールドは含まれません()、Ubuntuではパスワードハッシュは世界で読み取り可能なデータベースではなくデータベースに格納されるため、x常にである必要がありますxshadowpasswd
  • 正確に4桁の数字で構成されるUIDフィールド(:\d{4}:)。

したがって、これは受け入れられた答えのテクニックのかなり短くていくらか簡単な異形です。(そこに記載されている手法もうまくgrep機能し、サポートしていないGNU / Linux以外のシステムに移植できるという利点があり-Pます。)

「人間」UID範囲の再検討

非常に高いUIDに対応し、nobody明示的に確認する場合は、Oliのanswerのメソッドを使用できます。ただし、非常に高いUIDを持つユーザーを実際に人間と見なす必要がある場合、または他の特別な目的の非人間ユーザー(などnobody)である可能性が高い場合は、検討することをお勧めします。nobody実際には、このようなユーザーは一般的ではないため、実際にはこれはあなたの判断の呼び出しです。

妥協案として、新しく作成された「システム」以外のユーザーに実際に割り当てられている UIDの範囲内のユーザーをリストすることがあります。これadduser.conf次の場所で確認できます。

$ grep -E '^(FIRST|LAST)_UID' /etc/adduser.conf
FIRST_UID=1000
LAST_UID=29999

UIDの範囲が1000〜29999のユーザーをリストする2つの方法を次に示します。

getent passwd | grep -oP '^[^:]+(?=:x:[12]?\d{4}:)'
getent passwd | awk -F: '999<$3 && $3<30000 {print $1}'

あなたがスタイリストのように快適になりたいなら、,いですbasename。それは何よりも優れていlsます。lsを解析しない主な理由は、スタイルではなく、他のツールでより安全かつクリーンに実行できるジョブだからです。この場合、シェル:cd /home; getent passwd *
ムル

/ homeの信頼性が低いことに同意します(私にとっては役に立たない、私の答えを見てください)。あなたがスタイルについて説教しようとするなら、ピッキングを期待してください。
ムル

@muru私の最初のフレージングが、構文解析を避けることlsは通常スタイルに関するものだと人々を誤解させる可能性があることを理解しています。「不十分な出力」に関する2番目の箇条書きはこの問題をカバーしましたが、それは後のセクションで表示されます。この状況で構文解析lsが適切である理由を明確に言い換えました。より健全なアプローチをしばしば示す形をcd /home; getent passwd *とっていますが、実際のユーザーに対応していない奇妙な追加エントリがあるディレクトリの内容を読者が信じないように、それを避けました。ユーザーが存在します。/home
エリアケイガン

1

TL; DR:人間のユーザーのみがSystemAccount = falseを持ちます

もう1つの方法は、rootを無視しながらの出力をリストすることls /var/lib/AccountsService/users/ | grep -v rootです。奇妙なことに、gdm、グリーター/ログイン画面(または正式にはデスクトップマネージャー)もユーザーとしてリストされます。リストからだけでは、gdmが人間であるかどうかはわかりません。

より効率的で正しいアプローチは、そのフォルダー内のファイルを調べて、どのユーザーがとしてリストされているかを調べることSystemAccount=falseです。ワンライナーベローズはそれを達成します

grep SystemAccount=false /var/lib/AccountsService/users/* | awk -F '/' '{gsub(":","/");print $6}'


1
時々便利ですが、これはいくつかの比較的一般的なシナリオで失敗します。たとえば、Ubuntu 15.04最小システム(mini.isoディスプレイマネージャーまたはX11をインストールせずにインストール)には、1つの人間のユーザーアカウント/var/lib/AccountsService/usersがありますが、まだ空のディレクトリです。これは、すぐに使用できるUbuntu Serverのインストールでも同様に機能しないと思います。これは、作業を行う際にさらに、それはユーザアカウント「人間」作るもののやや限定的概念の下でそうする:でユーザーを作成useraddしても、なくては --system、中のファイルを作成しませんAccountsService/users
エリアケイガン

1

パーティに参加して、LDAPを使用するネットワークシステムを監督します。外部にホームディレクトリ/homeがあり、何百万ものUID(スクリプトの不具合)があります。したがって、現在の答えはどれも機能しません。私のために働くテストは、ユーザーが有効なログインシェルを持っているかどうかをチェックしています。有効なシェルは、にリストされているもの/etc/shellsです。最も単純な形式:

getent passwd | grep -wFf /etc/shells

ファイルにはコメント(または空の行)が含まれている場合があるため、コメントを除外する必要があります。

getent passwd | grep -wFf <(grep '^/' /etc/shells)

+1これは、これまでに提案された最も堅牢なアプローチかもしれません。表示するという欠点がありますがroot(通常、人間は通常の作業に使用するのではなく、一時的に特定の目的でルートになるため、これはおそらく人間のユーザーとは見なされません)、失敗する可能性は最も低いようです主要な方法。他の回答(私のものを含む)のメソッドは、ホームディレクトリが入っていない/home、他のゴミ入っている/home、UIDがおかしい、またはシステムがDMを使用していない場合、メソッドによって失敗することがあります。この答えは、これらすべてのシナリオで非常にうまく機能します。
エリアケイガン

1

buntuシステムでは、通常のユーザー(つまり、人間のユーザー)には、アカウントが最初に作成されたときに順番に割り当てられる1000から始まるUIDがあります。要するに、buntuシステムで作成された最初のアカウントのUIDは1000です。次に作成されたアカウントのUIDは1001です。以下同様です。

だから、システム上に存在するすべての人間のユーザーアカウントをリストする最も簡単な方法は、私の意見では/etc/passwd、ユーザーのUIDを含むファイルの3番目の列が1000以上、たとえば2000以下かどうかをチェックすることです(一般的なデスクトップPCが1,000を超えるユーザーアカウントを持つことはほとんどありません。そうは思いませんか?):

$ awk -F$':' '{ if ($3 >= 1000 && $3 < 2000) print $1; }' /etc/passwd

オリの答えを詳細に説明してくれてありがとう。また、除外する必要がありますnobody。=)
アナトリーテクトニック

1
誰も65534のUIDを持っていないため、他のすべての非人間ユーザーアカウントとして自動的に除外されるため、その必要はありません。
ミシャ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.