Daftar semua pengguna manusia

19

Bagaimana saya bisa mendaftar semua pengguna manusia yang saya buat? Saya sudah mencoba cat /etc/passwddan hanya daftar banyak hal.

techtonik anatoly
sumber

Jawaban:

18

Pengguna manusia memiliki UID mulai dari 1000, sehingga Anda dapat menggunakan fakta itu untuk menyaring non-manusia:

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

Ini memotong bidang pertama yang dibatasi (nama pengguna) dan ketiga (UID) /etc/passwd, kemudian menyaring untuk garis yang dihasilkan yang berakhir dengan titik dua dan empat digit, kemudian memotong bidang (nama pengguna) pertama dari itu, meninggalkan Anda dengan daftar pengguna dengan UID antara 1000 dan 9999.

Jika Anda memiliki lebih dari sembilan ribu pengguna di sistem Anda, ini akan gagal - tetapi Anda perlu membatasi hasilnya hanya untuk 4 digit UID agar tidak tertangkap nobody(UID 65534).


sumber
15

Ini cukup banyak apa yang dilakukan jawaban yang diterima , hanya dalam satu perintah, bukan tiga:

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

Dan terima kasih kepada Karel di komentar, nobodypengguna juga disaring.

Oli
sumber
@karel Ya, mungkin. Alih-alih memfilter oleh UID, saya memfilter nama pengguna itu secara eksplisit. Mungkin ada alasan untuk memiliki pengguna yang sah dengan UID yang tinggi ... Siapa tahu;)
Oli
9

Saya pribadi suka menggunakan hanya:

ls /home

Memang ini bukan daftar pengguna tetapi daftar direktori home mereka. Saat ini pengguna manusia yang ada di sistem akan memiliki direktori home /home, tetapi Anda dapat melihat direktori home dari pengguna sebelumnya yang juga dihapus.

Ini berfungsi untuk tujuan saya dan dapat bekerja untuk Anda juga. Misalnya, jika Anda ingin menghapus akun pengguna yang ternyata tidak ada lagi ( nonexistent-user) dan jalankan perintah

sudo deluser nonexistent-user

itu hanya akan memberi tahu Anda bahwa pengguna ini tidak ada.

Sam Hamblin
sumber
+1 Cara ini sederhana, itulah yang akan dilakukan oleh sebagian besar pengguna yang paling berpengalaman, dan saya pikir ini tidak kalah kuat dari metode yang memeriksa berbagai UID. Tampaknya lebih kecil kemungkinannya pengguna manusia akan memiliki direktori home di luar /home(yang tidak terhubung ke /home) daripada bahwa pengguna manusia akan memiliki UID di bawah 1000 (setelah semua, ini adalah metode yang paling umum untuk menjaga tampilan daftar manajer dari daftar pengguna pada layar login, yang kadang-kadang dapat dilakukan untuk pengguna manusia). Satu-satunya, kerugian yang relatif kecil di sini adalah yang lost+foundakan terdaftar pada sistem dengan /homepartisi terpisah .
Eliah Kagan
Masalah kecil, meskipun: apa yang terjadi jika pengguna dibuat dengan useradd --no-create-home username?
Sergiy Kolodyazhnyy
@Serg, saya pikir itu bermuara pada ambiguitas yang melekat dalam deskripsi masalah. Apakah akun tanpa direktori home benar-benar mewakili pengguna manusia? Dalam praktiknya, akun seperti itu biasanya - walaupun diakui tidak selalu - digunakan untuk tugas-tugas yang sangat khusus (biasanya oleh orang-orang dengan akun terpisah mereka sendiri) atau untuk pengguna yang dimaksudkan untuk mengakses sistem hanya melalui layanan spesifik dan terbatas. Tentu saja ada use case lain untuk useradd --no-create-home- direktori home mungkin sudah ada atau mungkin akan dibuat segera sesudahnya - tetapi ls /homemetode ini berfungsi dengan baik untuk case-case tersebut.
Eliah Kagan
4

Sementara itu mungkin tampak seperti ide yang jelas, sebenarnya ada ambiguitas dalam arti pengguna manusia . Apakah akun pengguna sengaja disembunyikan dari layar masuk karena digunakan hanya untuk tujuan khusus (tetapi oleh manusia) pengguna manusia? Bagaimana dengan ubuntupengguna (UID 999) pada live CD? Dan akun tamu di Ubuntu dibuat dengan cepat dan dihancurkan setelah keluar; apakah mereka pengguna manusia? Lebih banyak contoh dapat dibuat.

Oleh karena itu, sudah sepantasnya bahwa beberapa jawaban yang tidak setara diberikan. Solusi Saige Hamblin untuk menjalankan ls /homeadalah apa yang sebenarnya dilakukan orang, dan kecuali Anda menulis skrip, Anda mungkin harus menggunakannya.

Membuat ls /homeLebih Kuat

Tetapi mungkin Anda memiliki pengguna yang telah dihapus, tetapi direktori home yang masih ada di /homedalamnya, dan Anda harus menghindari daftar mereka. Atau mungkin karena alasan lain Anda harus memastikan hanya entri /homeyang terkait dengan akun nyata yang terdaftar.

Dalam hal ini, saya sarankan melewati nama-nama segala sesuatu dalam /homeuntuk getent(untuk mengambil passwdentri dari pengguna dengan nama-nama itu), hanya kolom username kemudian isolat dan display (dengan grep, sedatau awk, sesuai preferensi Anda). Salah satu dari ini akan dilakukan:

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

Ini harus bekerja dengan baik, karena Anda seharusnya tidak memiliki akun pengguna dengan spasi putih atau karakter kontrol dalam nama mereka; tidak bisa, tanpa mengkonfigurasi ulang Ubuntu untuk mengizinkannya ; dan jika Anda melakukannya, Anda memiliki masalah yang lebih besar. Jadi masalah yang biasa terjadi dengan penguraian lstidak dapat diterapkan. Tetapi meskipun itu benar-benar baik-baik saja di sini, jika Anda mempertimbangkan penggantian perintah dengan lsestetika yang tidak menyenangkan atau hanya kebiasaan buruk, Anda dapat memilih:

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

Ini tidak mengakomodasi spasi atau karakter kontrol baik. Saya memberi mereka hanya karena $(ls /home)terlihat salah bahkan ketika itu benar, dan dengan demikian menggosok banyak pengguna dengan cara yang salah. Dalam kebanyakan situasi, ada alasan nyata dan bagus untuk menghindari penguraianls , dan dalam situasi itu penguraian basename -abiasanya hanya sedikit lebih buruk. Namun, dalam situasi ini, karena keterbatasan pada karakter apa yang dapat terjadi secara praktis dalam nama pengguna , keduanya baik-baik saja.

Penjelasan, Manfaat, dan Kerugian

Saya menggunakan getentterutama karena ia menerima nama pengguna sebagai argumen untuk membatasi outputnya, tetapi juga karena itu sedikit lebih universal daripada memeriksa /etc/passwdsecara langsung, jika fasilitas otentikasi dan basis data kata sandi disediakan oleh layanan jaringan.

Metode ini memiliki manfaat tambahan di atas ls /homeitu, pada sistem dengan /homepartisi yang terpisah , lost+foundbiasanya muncul di output ls /home.

  • Dengan metode yang lebih kuat yang disajikan di atas, lost+foundhanya akan muncul jika kebetulan ada pengguna (manusia atau tidak) yang dipanggil lost+found, yang tidak mungkin.
  • Tetapi jika Anda memasukkan perintah secara interaktif daripada menulis skrip, ls /hometidak apa-apa - Anda tahu Anda tidak memiliki pengguna manusia yang dipanggil lost+found.

Jarang, metode ini (dalam variasi di atas) akan menghasilkan keluaran yang tidak memuaskan:

  • Jika direktori home pengguna ada di luar /home, atau tidak sama sekali, ini menunjukkan tetapi tidak menyiratkan akun tidak boleh dianggap mewakili pengguna manusia. Metode ini hanya mencantumkan pengguna ketika ada direktori dengan nama yang sama di /home.
  • Jika Anda telah membuat direktori tambahan /homeyang sebenarnya bukan direktori home siapa pun, dan mereka kebetulan memiliki nama yang sama dengan pengguna non-manusia yang ada - atau terdiri dari kata-kata yang dipisahkan oleh spasi putih, satu atau lebih yang memiliki nama yang sama sebagai pengguna non-manusia yang ada - maka beberapa pengguna non-manusia dapat dimasukkan dalam output.
    (Metode ini dapat diimplementasikan dengan loop dan getentdoa terpisah , sehingga pemisahan kata tidak menghasilkan output palsu. Tetapi kerumitannya tidak dijamin; pada dasarnya, jika Anda menggunakan /homesesuatu selain tempat untuk direktori home pengguna, metode ini akan tidak menghasilkan output yang dapat diandalkan.)

Membuat Pemeriksaan UID Lebih Mudah

Jika Anda memutuskan untuk menggunakan metode yang memeriksa ID pengguna untuk memastikan mereka berada dalam kisaran kemungkinan akun yang mewakili manusia, seperti dalam jawaban yang diterima atau jawaban Oli , maka saya menyarankan ini untuk singkatnya:

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

Ini menggunakan ekspresi reguler Perl ( -P) untuk menunjukkan:

  • teks di awal baris ( ^) yang mengandung no :s ( [^:]+) - ini adalah bidang pertama, seperti :pemisah bidang dalampasswd
  • yang mendahului tetapi tidak termasuk ( (?= )) bidang kata sandi x- harus selalu demikian x, karena di Ubuntu kata sandi disimpan di dalam shadowbasis data, bukan passwdbasis data yang dapat dibaca dunia
  • dan bidang UID yang terdiri dari tepat 4 digit ( :\d{4}:).

Dengan demikian, ini merupakan varian teknik yang secara signifikan lebih pendek dan lebih sederhana dalam jawaban yang diterima . (Teknik yang dijelaskan di sini juga berfungsi dengan baik, dan memang menguntungkan untuk portabel ke sistem non-GNU / Linux yang greptidak mendukung -P.)

Mempertimbangkan Kisaran UID "Manusia"

Jika Anda ingin mengakomodasi UID yang sangat tinggi dan memeriksa nobodysecara eksplisit, Anda dapat menggunakan metode dalam jawaban Oli . Anda mungkin ingin mempertimbangkan, bagaimanapun, jika pengguna dengan UID sangat tinggi harus benar-benar dianggap manusia, atau jika mereka lebih cenderung menjadi pengguna non-manusia dengan tujuan khusus lainnya (seperti nobody). Dalam praktiknya, pengguna seperti itu - selain - nobodyjarang terjadi, jadi ini adalah penilaian Anda.

Kemungkinan kompromi adalah untuk membuat daftar pengguna dalam kisaran UID yang benar-benar ditugaskan untuk pengguna yang baru dibuat, bukan "sistem". Anda dapat memeriksa ini diadduser.conf :

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

Berikut adalah dua cara untuk membuat daftar pengguna yang kisaran UID-nya dari 1000 hingga 29999:

getent passwd | grep -oP '^[^:]+(?=:x:[12]?\d{4}:)'
getent passwd | awk -F: '999<$3 && $3<30000 {print $1}'
Eliah Kagan
sumber
Jika Anda ingin gaya menyenangkan, basenameitu jelek. Tidak lebih baik dari itu ls. Alasan utama kita tidak menguraikan adalah bahwa itu adalah pekerjaan yang dapat dilakukan oleh alat lain jauh lebih aman dan bersih, bukan gaya. Dalam hal ini, shell: cd /home; getent passwd *.
muru
Saya setuju dengan Anda di / rumah menjadi tidak dapat diandalkan (tidak ada gunanya bagi saya, lihat jawaban saya). Saya hanya mengatakan bahwa jika Anda akan berkhotbah tentang gaya, mengharapkan nitpicking.
muru
@muru Saya melihat bagaimana ungkapan orisinal saya dapat menyesatkan orang untuk berpikir menghindari parsing lsbiasanya tentang gaya. Poin kedua tentang "output yang tidak memuaskan" mencakup masalah ini, tetapi muncul di bagian selanjutnya. Saya telah menulis ulang untuk mengklarifikasi mengapa parsing lssesuai dalam situasi ini . Meskipun cd /home; getent passwd *mengambil bentuk yang sering menunjukkan pendekatan yang lebih baik, saya telah menghindarinya agar tidak membuat pembaca percaya pada isi /homedirektori, dengan entri tambahan aneh yang tidak sesuai dengan pengguna nyata, entah bagaimana masih bisa diandalkan sebagai panduan untuk apa pengguna ada.
Eliah Kagan
1

TL; DR : hanya pengguna manusia yang memiliki SystemAccount = false

Salah satu cara lain adalah dengan mendaftar keluaran sementara mengabaikan root ls /var/lib/AccountsService/users/ | grep -v root. Sekarang, ada quirk - gdm, layar penyapa / login (atau lebih desktop manager) juga terdaftar sebagai pengguna. Jadi dari daftar kami tidak tahu apakah gdm itu manusia atau bukan.

Pendekatan yang lebih efisien dan benar adalah memeriksa file-file di folder itu dan mencari tahu pengguna mana yang terdaftar SystemAccount=false. Satu garis di bawah mencapai itu

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

Sergiy Kolodyazhnyy
sumber
1
Meskipun terkadang berguna, ini gagal dalam beberapa skenario yang relatif umum. Sebagai contoh, pada sistem minimal Ubuntu 15.04 saya (diinstal dari mini.isodan tanpa manajer tampilan atau X11 diinstal), saya memiliki satu akun pengguna manusia - namun /var/lib/AccountsService/usersmerupakan direktori kosong. Saya berharap ini juga tidak akan bekerja pada instalasi Ubuntu Server out-of-the-box. Lebih jauh lagi, ketika ini berhasil, ia melakukannya di bawah gagasan yang agak membatasi tentang apa yang membuat akun pengguna "manusia": membuat pengguna dengan useradd, bahkan tanpa --system , tidak membuat file AccountsService/users.
Eliah Kagan
1

Bergabung dengan partai, saya mengawasi sistem jaringan menggunakan LDAP, memiliki direktori home di luar /homedan UID (karena kesalahan scripting) dalam jutaan. Karena itu, tidak ada jawaban saat ini yang berfungsi. Tes yang berfungsi untuk saya adalah memeriksa apakah pengguna memiliki shell login yang valid. Shell yang valid adalah yang terdaftar di /etc/shells. Bentuk paling sederhana:

getent passwd | grep -wFf /etc/shells

File mungkin berisi komentar (atau baris kosong), jadi orang mungkin harus memfilternya:

getent passwd | grep -wFf <(grep '^/' /etc/shells)
muru
sumber
+1 Ini mungkin pendekatan yang paling kuat yang disarankan sejauh ini. Meskipun memiliki kelemahan untuk ditampilkan root(yang mungkin seharusnya tidak dianggap sebagai pengguna manusia, karena manusia biasanya menjadi root untuk sementara dan untuk tujuan tertentu, daripada menggunakannya untuk pekerjaan rutin mereka), sepertinya itu adalah yang paling tidak mungkin gagal dalam cara utama. Metode dalam jawaban lain (termasuk tambang) mungkin gagal, tergantung pada metode, jika direktori rumah tidak ada /home, sampah lain ada di dalam /home, UID aneh, atau sistem tidak menggunakan DM. Jawaban ini berfungsi dengan baik di semua skenario itu.
Eliah Kagan
1

Pada sistem buntu, pengguna biasa (pengguna manusia, yaitu) memiliki UID yang dimulai dengan 1000 yang ditugaskan secara berurutan kepada mereka ketika akun mereka pertama kali dibuat. Intinya semua ini adalah bahwa akun pertama yang dibuat pada sistem buntu memiliki UID 1000. Yang berikutnya dibuat memiliki UID 1001. Dan seterusnya dan seterusnya.

Jadi, cara paling sederhana untuk mendaftar semua akun pengguna manusia yang ada di sistem, menurut saya, adalah memeriksa apakah kolom ketiga dalam /etc/passwdfile yang berisi UID pengguna lebih besar atau sama dengan 1000 dan kurang dari, katakanlah, 2000 (Sangat tidak mungkin PC desktop biasa memiliki lebih dari seribu akun pengguna, bukan begitu?):

$ awk -F$':' '{ if ($3 >= 1000 && $3 < 2000) print $1; }' /etc/passwd
misha
sumber
Terima kasih telah menjelaskan jawaban Oli dengan detail. Anda juga perlu memfilter nobody. =)
anatoly techtonik
1
Anda tidak harus melakukannya karena tidak ada seorang pun yang memiliki UID 65534 dan dengan demikian secara otomatis disaring sebagai semua akun pengguna bukan manusia lainnya.
misha