2013-05-19 12 views

Odpowiedz

1

Po prostu próbujesz uzyskać listę wszystkich użytkowników z/etc/passwd? Jeśli tak, wierzę, że byłoby to łatwiejsze rozwiązanie:

cut -d":" -f1 /etc/passwd 

Edit:

W przypadku tylko chcesz listę użytkowników zdefiniowanych przez użytkownika (nie użytkowników systemu), można użyć jednego z nich:

grep -E ":[0-9]{4,6}:[0-9]{4,6}:" /etc/passwd | cut -d: -f1 

^ta zakłada system używa 1000 i aż do UID i GID dla zdefiniowanych przez użytkownika użytkowników

grep /home /etc/passwd | cut -d: -f1 

^Zakłada to, że każdy użytkownik zdefiniowany przez użytkownika ma katalog osobisty.

Inne rozwiązania zależą od bardziej szczegółowych kryteriów i ustawień systemu.

+0

Działa również jako cut -f1 -d:/etc/passwd – arheops

+0

Nie. Od 1000, uważam "użytkowników" .. w/wyjątkiem "nikt" .. – Robottinosino

+0

Fajne pomysły w edycji. Nauczyłem się czegoś. Wciąż wygląda na włamywacza, prawda? – Robottinosino

2

jestem pewien, dlaczego robisz to tylko> 1000, beacuase na systemie RedHat rozpocząć od 500.

Dla mnie to OK pracy skrypt awk:

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

Tylko korzysta z hasłami:

awk -F: '{if(!(($2 == "!!")||($2 == "*"))) print $1}' /etc/shadow 
+0

Masz całkowitą rację, baza została wybrana niepoprawnie. 1000 to głupia "magiczna liczba", moja wina ... ale potem ... to jest 500 ?! A może nie? – Robottinosino

+0

To nie jest potrzebne, twój połączony dokument podaje operatory w kolejności * zwiększenia * pierwszeństwa, więc '&&' ma niższy priorytet niż '> =' i '<'. –

+0

dla redhat jest 500. Wygląda na to, że żadna usługa nie była używana po 499. Ale tak naprawdę jest tylko dla RHEL. Możesz dodać coś takiego jak "grep/home" lub "grep/bin/bash" w zależności od ustawień systemu. Możesz również uzyskać tylko użytkowników z hasłem - patrz wyżej. – arheops

2

Wyodrębnij minimalne i maksymalne ID użytkownika z /etc/login.defs, a następnie wybierz użytkowników z identyfikatorami między tymi marginesami z /etc/passwd:

UID_MIN=$(awk '/^UID_MIN/ {print $2}' /etc/login.defs) 
UID_MAX=$(awk '/^UID_MAX/ {print $2}' /etc/login.defs) 

awk -F: -v min=$UID_MIN -v max=$UID_MAX '$3 >= min && $3 <= max{print $1}' /etc/passwd 
+0

Na marginesie, 'if' jest zbyteczne ... po prostu rób' '$ 3> = min && 3 $ =

+1

Spowoduje to pominięcie wielu, w niektórych przypadkach, prawie wszystkich użytkowników w witrynach korzystających z LDAP, NIS i innych mechanizmów użytkownika, które obejmują bazy danych przechowywane poza plikiem/etc/passwd. –

+1

@ AlexNorth-Keys True. Miałem jednak wrażenie, że szuka lokalnych użytkowników. –

12

Niektóre systemy uniksowe nie używają /etc/passwd lub mają użytkowników, którzy nie są tam określeni. Zamiast przeczytać /etc/passwd należy użyć getent passwd.

Mój system ma również użytkowników, którzy są wyłączeni i mogą dłużej logować się przy użyciu komendy logowania ustawionej na /bin/false lub /usr/sbin/nologin. Prawdopodobnie również chcesz je wykluczyć.

Oto, co działa dla mnie w tym arheops polecenia awk i kod Ansgar, aby uzyskać min i max od login.defs:

getent passwd | \ 
grep -vE '(nologin|false)$' | \ 
awk -F: -v min=`awk '/^UID_MIN/ {print $2}' /etc/login.defs` \ 
-v max=`awk '/^UID_MAX/ {print $2}' /etc/login.defs` \ 
'{if(($3 >= min)&&($3 <= max)) print $1}' | \ 
sort -u 
+0

Dobrze działa w mojej sieci domowej, pomimo użytkowników LDAP, automatycznie kataloguje katalogi domowe z dziwnymi ścieżkami itp. Tworzy duplikaty dla użytkowników, którzy mają zarówno wpisy LDAP, jak i zastępcze/etc/passwd, ale poza tym, miło. –

+0

Duplikaty można wyeliminować, dołączając '| sort -u'. –

+0

... lub przy użyciu tymczasowej tablicy jako części polecenia 'awk'. –

2

Oto inne podejście, że tylko ikra jednego programu zewnętrznego, getent (sugerowane przez @AnsgarWiechers) aby korzystać z lokalnych i sieciowych baz danych passwd. Ten redukuje liczbę widelców do jednego dla samej siebie. Jego przenośność jest jednak nieco ograniczona przez wymaganie bash4.

get_users() 
{ 
    local IFS=$' \t#' 
    while read var val ; do 
     case "$var" in 
      UID_MIN) min="$val" ;; 
      UID_MAX) max="$val" ;; 
     esac 
    done < /etc/login.defs 
    declare -A users 
    local IFS=: 
    while read user pass uid gid gecos home shell; do 
     if ((min <= uid && uid <= max)) && [[ ! $shell =~ '/(nologin|false)$' ]]; then 
      users[$user]=1 
     fi 
    done < <(getent passwd 2>/dev/null) 
    echo ${!users[@]} 
} 
+0

+1. Należy jednak wspomnieć, że wymaga to 'bash4', więc nie jest to rozwiązanie bardzo przenośne. –

+0

Dobra uwaga. ;-) –

1

Oto uproszczenie odpowiedzi @ StephenOstermillera, która polega na wykonaniu tylko dwóch procesów. Wydaje mi się, że jest to również łatwiejsze do odczytania (pod warunkiem, że znasz język awk NR==FNR).

getent passwd | 
awk 'NR==FNR { if ($1 ~ /^UID_(MIN|MAX)$/) m[$1] = $2; next } 
{ split ($0, a, /:/); 
    if (a[3] >= m["UID_MIN"] && a[3] <= m["UID_MAX"] && a[7] !~ /(false|nologin)$/) 
    print a[1] }' /etc/login.defs - 

Różne wzory podziału w dwóch nakładach to trochę brodawek; może uda ci się to jakoś bardziej elegancko naprawić.