답변:
휴먼 사용자는 1000부터 UID를 시작하므로 해당 사실을 사용하여 비인간을 필터링 할 수 있습니다.
cut -d: -f1,3 /etc/passwd | egrep ':[0-9]{4}$' | cut -d: -f1
첫 번째 (사용자 이름) 및 세 번째 (UID) 콜론으로 구분 된 필드를에서 /etc/passwd
잘라낸 다음 콜론과 4 자리 숫자로 끝나는 결과 줄을 필터링 한 다음 첫 번째 (사용자 이름) 필드를 잘라 내고 UID가 1000에서 9999 사이 인 사용자
시스템에 9 천명 이상의 사용자가있는 경우 실패합니다. 그러나이를 포착하지 않으려면 결과를 4 자리 UID로 제한해야합니다 nobody
(UID 65534).
나는 개인적으로 다음을 사용하고 싶습니다.
ls /home
분명히 이것은 사용자 목록이 아니라 홈 디렉토리 목록입니다. 현재 시스템의 기존 사용자는에 홈 디렉토리가 /home
있지만 제거 된 이전 사용자의 홈 디렉토리도 볼 수 있습니다.
이것은 내 목적으로 작동하며 귀하에게도 효과가있을 수 있습니다. 예를 들어, 더 이상 존재하지 않는 사용자 계정을 삭제하려는 경우 ( nonexistent-user
) 명령을 실행하십시오.
sudo deluser nonexistent-user
이 사용자가 존재하지 않는다는 것을 알려줄뿐입니다.
/home
(결론되지 않음 /home
) (디스플레이 관리자가 목록을 표시하지 못하게하는 가장 일반적인 방법입니다) 로그인 화면의 사용자 (인간 사용자를 위해 수행 될 수 있음). 여기서 비교적 사소한 단점은 lost+found
별도의 /home
파티션이있는 시스템에 표시 된다는 것 입니다.
useradd --no-create-home username
? 로 생성되면 어떻게됩니까 ?
useradd --no-create-home
홈 디렉토리가 이미 존재하거나 그 후에 곧 생성 될 수도있는 또 다른 유스 케이스가 있지만이 경우에는 ls /home
메소드가 제대로 작동합니다.
분명한 아이디어처럼 보이지만 실제로는 사용자 의 의미에 모호성이 있습니다 . 사용자 계정은 인간 사용자가 특수 목적으로 만 사용하기 때문에 의도적으로 로그인 화면에 숨겨져 있습니까? ubuntu
라이브 CD 의 사용자 (UID 999)는 어떻습니까? 그리고 우분투의 게스트 계정은 즉시 생성되어 로그 아웃 후에 파기됩니다. 그들은 인간 사용자입니까? 더 많은 예가 고안 될 수있다.
따라서 여러 가지 비등가적인 답변을 제공하는 것이 적합합니다. Saige Hamblin의 달리기 솔루션 은 ls /home
사람들이 실제로 하는 일이며, 스크립트를 작성하지 않는 한 그냥 사용해야합니다.
ls /home
더 견고한 만들기그러나 사용자는 제거되었지만 홈 디렉토리는 여전히 존재하는 사용자가 있으므로 해당 사용자를 /home
나열하지 않아야합니다. 또는 다른 이유로 /home
실제 계정 에 해당하는 항목 만 나열해야합니다.
이 경우, 나는 모든 것을의 이름을 통과 제안 /home
을 getent
합니다 (검색 할 passwd
(와 그 이름을 가진 사용자의 항목을), 다음 분리 및 디스플레이 단지 사용자 이름 필드 grep
, sed
또는 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
실제로 사람의 홈 디렉토리하지 않습니다, 그리고 그들이 기존의 인간이 아닌 사용자와 동일한 이름을 가질 일이 - 또는 단어로 구성 하나 이상의 어떤의이 같은 이름을 가진, 공백으로 구분 기존의 비인간 사용자로서 일부 비인간 사용자가 출력에 포함될 수 있습니다. getent
있도록 호출 단어 분할이 스퓨리어스 출력을 생성하지 않습니다하지만 복잡성은 보증되지 않으며. 기본적으로, 당신이 사용하는 경우 /home
사용자의 홈 디렉토리를위한 장소가 아닌 다른 무언가로,이 방법은 것입니다 신뢰할 수있는 출력을 생성하지 않습니다.)허용 된 답변 또는 Oli의 답변 에서처럼 사용자 ID를 확인하여 사람을 나타내는 계정의 범위에 있는지 확인하는 방법을 사용하기로 결정한 경우 간결하게 제안합니다.
getent passwd | grep -oP '^[^:]+(?=:x:\d{4}:)'
이것은 Perl 정규 표현식 ( -P
)을 사용하여 다음을 표시합니다.
^
)에는 포함하지 :
들 ( [^:]+
) -로이 첫 번째 필드 인 :
필드 세퍼레이터 인passwd
(?=
)
암호 필드 는 포함하지 않아야합니다 ( )x
x
shadow
passwd
:\d{4}:
) 로 구성된 UID 필드 .따라서 이것은 허용 된 답변 에서 기술의 상당히 짧고 다소 간단한 변형입니다 . (이 기술은 잘 작동하며을 grep
지원하지 않는 GNU / Linux 이외의 시스템으로 이식 할 수 있다는 이점이 있습니다 -P
.)
매우 높은 UID를 수용하고 nobody
명시 적으로 확인하려면 Oli의 답변 에서 메소드를 사용할 수 있습니다 . 그러나 UID가 매우 높은 사용자가 실제로 사람으로 간주되거나 다른 특수 목적의 비인간 사용자 일 가능성이 더 높은 경우 (예 :)를 고려할 수 있습니다 nobody
. 실제로 그러한 사용자 (외에도) nobody
는 드물기 때문에 실제로 이것은 사용자 의 판단입니다.
가능한 한 타협은 실제로 새로 생성 된 "시스템"이 아닌 사용자에게 할당되고있는 UID 범위의 사용자를 나열하는 것입니다 . 이 검사 할 수 있는adduser.conf
:
$ grep -E '^(FIRST|LAST)_UID' /etc/adduser.conf
FIRST_UID=1000
LAST_UID=29999
UID가 1000에서 29999 범위 인 사용자를 나열하는 두 가지 방법은 다음과 같습니다.
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 *
.
ls
것이 일반적으로 스타일에 대해 오해하게 만들 수있는 방법을 본다 . "만족스럽지 않은 출력"에 대한 두 번째 글 머리표는이 문제를 다루었지만 이후 섹션에 나타납니다. 이 상황에서 구문 분석 ls
이 적합한 이유를 명확히하기 위해 다시 말한 바 있습니다 . 좀 더 건전한 접근 방식을 나타내는 형태를cd /home; getent passwd *
취하고 있지만 , 독자가 디렉토리 의 내용을 믿지 않도록하기 위해 피했습니다. 사용자가 존재합니다. /home
TL; DR : 인간 사용자 만 SystemAccount = false
다른 방법은 root를 무시하면서 출력을 나열하는 것 ls /var/lib/AccountsService/users/ | grep -v root
입니다. 이제 quirk-gdm이 있으며, 인사 / 로그인 화면 (또는 공식적으로 데스크탑 관리자)도 사용자로 표시됩니다. 따라서 목록에서 gdm이 사람인지 아닌지를 알 수 없습니다.
보다 효율적이고 올바른 방법은 해당 폴더에있는 파일을 살펴보고 어느 사용자가 포함되어 있는지 확인하는 것입니다 SystemAccount=false
. 한 줄짜리 벨로우즈는
grep SystemAccount=false /var/lib/AccountsService/users/* | awk -F '/' '{gsub(":","/");print $6}'
mini.iso
디스플레이 관리자 나 X11이 설치되어 있거나 설치되어 있지 않음)에는 하나의 휴먼 사용자 계정이 있지만 /var/lib/AccountsService/users
빈 디렉토리입니다. 기본 제공 Ubuntu 서버 설치에서도 이와 유사하게 작동하지 않을 것으로 예상됩니다. 이 작업을 수행 할 때 또한, 그것은 사용자 계정 "인간"무엇이 다소 제한적인 개념에서 그렇게 :와 사용자를 만들기 useradd
도, 하지를 --system
,에 파일을 생성하지 않습니다 AccountsService/users
.
파티에 참여하면서 LDAP를 사용 /home
하여 수백만의 외부 홈 디렉토리 와 UID (스크립팅 결함으로 인해)가있는 네트워크 시스템을 감독합니다 . 따라서 현재 답변 중 아무것도 작동하지 않습니다. 나를 위해 작동하는 테스트는 사용자에게 유효한 로그인 쉘이 있는지 확인하는 것입니다. 유효한 쉘은에 나열된 쉘입니다 /etc/shells
. 가장 간단한 형태 :
getent passwd | grep -wFf /etc/shells
파일에 주석 (또는 빈 줄)이 포함될 수 있으므로 주석을 필터링해야합니다.
getent passwd | grep -wFf <(grep '^/' /etc/shells)
root
( 아마도 인간 사용자로 간주되어서 는 안되지만 , 인간은 보통 정기적 인 작업에 사용하기보다는 일시적이고 특정한 목적으로 근본이되기 때문에) 실패 할 가능성이 가장 적은 것 같습니다 어떤 중요한 방법. 홈 디렉토리에없는 경우 (광산 포함) 다른 답변의 방법, 방법에 따라 실패 할 수 있습니다 /home
, 다른 쓰레기 입니다 에 /home
UID를 이상한, 또는 시스템은 DM을 사용하지 않습니다. 이 답변은 모든 시나리오에서 잘 작동합니다.
buntu 시스템에서 일반 사용자 (휴먼 사용자)는 1000으로 시작하는 UID를 가지고 있으며 이는 처음 계정을 만들 때 순차적으로 할당됩니다. 이 모든 결론은 buntu 시스템에서 생성 된 첫 번째 계정의 UID가 1000이라는 것입니다. 다음으로 생성 된 계정의 UID는 1001입니다.
따라서 시스템에 존재하는 모든 사용자 계정을 나열하는 가장 간단한 방법 /etc/passwd
은 사용자의 UID를 포함하는 파일 의 세 번째 열 이 1000 이상이고 2000 이하인지 확인하는 것입니다. (일반적인 데스크탑 PC에 1000 개 이상의 사용자 계정이있을 가능성은 거의 없습니다.)
$ awk -F$':' '{ if ($3 >= 1000 && $3 < 2000) print $1; }' /etc/passwd
nobody
. =)