Linux 시스템에서 UID가 1000보다 큰 모든 로컬 사용자 계정을 삭제하는 쉘 스크립트를 작성하는 방법은 무엇입니까?
이것이 내가 지금까지 가지고 있는 것입니다:
#!/bin/bash
for userid in `/etc/passwd`
do
if ((“userid” >= 1000)); then
userdel -r $user
done
UID가 1000보다 큰 모든 계정을 삭제하는 조건을 설정하는 방법은 무엇입니까? 제가 못찾은 부분이군요. 지금까지 제가 한 일이 맞는지조차 확신할 수 없지만 비슷한 문제가 있지만 약간 다른 다른 게시물에서 이에 대해 읽었습니다.
답변1
다음 awk
명령은 UID가 1000 이상인 모든 로컬 사용자의 사용자 이름을 인쇄하고 이름이 지정된 사용자 nobody
(가장 가능성이 높은 사용자) 는 건너뜁니다.아니요삭제하고 싶습니다):
awk -F : '$3 >= 1000 && $1 != "nobody" { print $1 }' /etc/passwd
파일을 구분된 필드가 있는 줄 기반 레코드 /etc/passwd
집합으로 구문 분석합니다 . :
세 번째 필드의 값이 1000보다 크거나 같은지 테스트하고 첫 번째 필드가 아닌지 확인한 nobody
다음 첫 번째 필드를 인쇄합니다. UID가 높은 특수 계정에 액세스 $1 != "nobody"
하지 않도록 두 번째 테스트를 변경할 수 있습니다 .$3 < 10000
그런 다음 루프를 사용하여 이름을 읽고 한 번에 하나씩 삭제할 수 있습니다(참조스티븐의 대답다음을 사용하여 이를 수행하는 방법을 알아보세요 xargs
.
awk -F : '$3 >= 1000 && $1 != "nobody" { print $1 }' /etc/passwd |
while IFS= read -r name; do
userdel -r "$name"
done
답변2
다음과 같아야 합니다.
getent passwd |
awk -F: '$3 >= 1000 {print $1}' |
xargs -n1 -rd '\n' echo userdel -r --
echo
(올바른 것 같으면 삭제하세요.) 이는 GNU 구현을 가정 xargs
하지만 일반적으로 내장되지 않은 Linux 시스템(사용자 관리를 수행할 시스템)에서 사용됩니다.
getent passwd
/etc/passwd
, postgresql, sqlite3, LDAP 에 저장되어 있는지 여부에 관계없이 passwd 사용자 데이터베이스를 덤프합니다 .
이 데이터베이스 덤프에서 항목은 콜론으로 구분되며 첫 번째 필드는 사용자 이름이고 세 번째 필드는 사용자 ID입니다.
awk
이러한 유형의 데이터를 처리하기 위한 확실한 선택입니다.
-F:
(의 약어 ) 로 호출하고 -v FS=:
필드 구분 기호를 로 설정 :
하고 각 레코드에 대해 세 번째 필드가 1000보다 크거나 같은 숫자인 경우 첫 번째 필드를 인쇄합니다.
xargs
해당 출력을 가져오고( n
ewline d
제한으로 처리됨) 각 1
항목에 대해 , echo
, with 를 호출하고 해당 항목을 인수로 사용합니다 userdel
.-r
--
사용자 이름만 고려하려면 getent passwd |
으로 바꾸십시오.</etc/passwd
/etc/passwd
nobody
@Kusalananda가 말했듯 이 삭제하고 싶지 않은 시스템 계정이 있을 수 있습니다 .
예를 들어 내 시스템에서 다음을 발견했습니다.
libvirt-qemu:x:64055:108:Libvirt Qemu,,,:/var/lib/libvirt:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
따라서 $3 >= 1000 && $3 < 60000
또는 $3 >= 1000 && $6 ~ "^/home/"
(아래의 홈 디렉토리 /home
) 또는 $7 !~ "nologin"
(쉘에 로그인이 포함되지 않음), 특정 그룹의 구성원, 유효한 비밀번호 등 선택 사항에 더 많은 조건을 추가할 수 있습니다.
표준 입력은 /dev/null이므로 아무 것도 묻는 메시지가 표시 userdel
되지 않습니다. 이를 방지하려면 다음과 같이 다시 작성할 수 있습니다.
xargs -n1 -rd '\n' -a <(
getent passwd |
awk -F: '$3 >= 1000 {print $1}'
) echo userdel -r --
이번에는 stdin 대신 xargs
나중에 전달된 파일에서 입력을 가져오고 stdin은 그대로 둡니다.-a
userdel
이 경우 파일 이름은 ksh 스타일 프로세스 대체(bash에서도 지원됨)의 결과이며 <(...)
파이프 경로로 확장되고 getent | awk
.