2013-05-19 47 views

回答

1

所以你只是想從/ etc/passwd獲得所有用戶的列表?如果是的話,我相信這將是一個簡單的解決方案:

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

編輯:

如果你只是想用戶自定義的用戶(不是系統的用戶)的列表,你可以使用一個這些:

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

^這裏假設你的系統使用1000只及以上的UID和GID爲用戶自定義的用戶

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

^這假定每個用戶定義的用戶都有一個主目錄。

其他解決方案取決於更詳細的標準和您的系統設置。

+0

也可以用作cut -f1 -d:/ etc/passwd – arheops

+0

不可以。從1000,我認爲「用戶」.. w /「沒有人」的例外.. – Robottinosino

+0

在您的編輯很酷的想法。我學到了東西。仍然看起來像一個黑客,不是嗎? – Robottinosino

2

我不清楚你爲什麼只> 1000,RedHat的系統上beacuase從500

開始對於我這個awk腳本工作確定:

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

只有使用密碼

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

你是完全正確的,基地被錯誤地選擇。 1000是一個愚蠢的「魔術數字」,我的錯......但那麼......所以是500?!或者,不是嗎? – Robottinosino

+0

這不是必需的,你的鏈接文檔按*增加*優先順序來指定運算符,所以'&&的優先級低於'> ='和'<'。 –

+0

爲紅帽它是500.看起來像499後沒有使用服務。但這實際上只適用於RHEL。您可以根據系統設置添加「grep/home」或「grep/bin/bash」等內容。你也可以只有用戶使用密碼 - 見上面。 – arheops

2

/etc/login.defs中提取最小和最大用戶ID,然後從/etc/passwd中選擇這些邊距之間的ID的用戶:

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

在附註中,'if'是多餘的...只要做'$ 3> = min && $ 3 <= max {print $ 1} 「'。 –

+1

這在很多情況下會錯過幾乎所有使用LDAP,NIS和其他用戶機制的用戶,這些用戶機制包括存儲在/ etc/passwd文件之外的數據庫。 –

+1

@ AlexNorth-Keys True。不過,我的印象是他在尋找本地用戶。 –

12

某些unix系統不使用/etc/passwd,或者有沒有在那裏指定的用戶。您應該使用getent passwd而不是閱讀/etc/passwd

我的系統也有用戶被禁用,並可以更長的登錄與他們的登錄命令設置爲/bin/false/usr/sbin/nologin。您可能也想排除它們。

這裏是我,包括arheops awk命令和ANSGAR的代碼從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

在我的家庭網絡上很好地工作,儘管LDAP用戶,自動安裝的主目錄有奇怪的路徑等等。它確實爲那些同時擁有LDAP和fallback/etc/passwd項目的用戶生成重複項目,但其他項目很好。 –

+0

重複可以通過追加'|來消除排序-u'。 –

+0

...或通過使用臨時數組作爲awk命令的一部分。 –

2

這裏的另一種方法,只有派生一個外部程序,getent(由@AnsgarWiechers建議)因此將使用本地和網絡密碼數據庫。這一個將叉子的數量減少到getent本身的數量。然而,它的可移植性受限於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。你應該提到,雖然這需要'bash4',所以不是一個非常便攜的解決方案。 –

+0

好點。 ;-) –

1

下面是對@ StephenOstermiller的答案的簡化,它只有兩個過程才能完成。我認爲它也更容易閱讀(假如你熟悉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 - 

兩個輸入的不同分割模式是一個疣;也許你可以用某種方式更優雅地修復它。