모든 사용자 이름 및/또는 홈 디렉터리를 어떻게 나열할 수 있나요?

모든 사용자 이름 및/또는 홈 디렉터리를 어떻게 나열할 수 있나요?

컴퓨터에 있는 모든 사용자의 디렉터리를 나열하고 싶습니다. 일반적으로 저는 이렇게 합니다:

ls -l /home

그러나 나는 다른 사람의 컴퓨터, 즉 myHome과 같이 집이라고 부르지 않는 컴퓨터에 배포될 스크립트에서 이를 사용하고 있습니다.

그래서 나는 그것을 ls -l ~.

어떻게 요약할 수 있나요?

답변1

많은 시스템에는 getent파일 내용을 나열하거나 쿼리하는 명령이 있습니다.이름 서비스passwd, group, services, protocols... 등의 데이터베이스

getent passwd | cut -d: -f6

데이터베이스에 있는 모든 사용자의 홈 디렉토리를 나열합니다(6번째 콜론으로 구분된 필드).열거된.

사용자 이름 자체는 첫 번째 필드에 있으므로 사용자 이름 목록은 다음과 같습니다.

getent passwd | cut -d: -f1

(이것은 이러한 사용자가 시스템에 로그인할 수 있거나 홈 디렉토리가 생성되었음을 의미하는 것이 아니라 시스템에 알려지고 사용자 ID로 변환될 수 있다는 것을 의미합니다.)

열거할 수 없는 데이터베이스의 경우 가능한 각 사용자 ID를 개별적으로 쿼리해 볼 수 있습니다.

getent passwd {0..65535} | cut -d: -f1,6

(이것은 uid가 65535(일부 시스템은 더 많은 것을 지원함)에서 멈추고 쉘이 zsh의 {x..y}중괄호 확장 형식을 지원한다고 가정합니다.) 그러나 사용자 데이터베이스가 네트워크로 연결된(그리고 로컬 캐시가 제한되어 있는) 시스템(예: LDAP, NIS+, SQL)에서는 이 작업을 자주 수행하고 싶지 않습니다. 디렉터리 서버)에서 이러한 모든 쿼리를 수행합니다.

이는 또한 동일한 uid를 공유하는 여러 사용자가 있는 경우 uid당 하나의 항목만 가져오므로 다른 항목은 무시한다는 의미입니다.

없는 경우 getent다음을 수행할 수 있습니다 perl.

perl -le 'while (@e = getpwent) {print $e[7]}'

( 사용자 이름 getent passwd) $e[0]또는:

perl -le 'for ($i=0;$i<65536;++$i) {
  if (@e = getpwuid $i) {print $e[0] ": " $e[7]}}'

getent passwd {0..65535}같은 경고가 있습니다 .

쉘에서는 ~user얻은 홈 디렉토리를 사용할 수 있지만 user대부분의 쉘에서는 제한된 사용자 이름 세트에서만 작동합니다( ~이 확산 연산자가 지원하는 사용자 이름에 허용되는 문자 목록은 쉘마다 다름). 일부 쉘(포함 )에서는 작동하지 않습니다. 작동하지 않습니다( bash사용자 이름이 변수에 저장되어 있을 때 ~$user도움이 필요합니다 ). eval그리고 여전히 사용자 이름 목록을 얻을 수 있는 방법을 찾아야 합니다.

일부 쉘에는 사용자 이름 목록을 가져오는 기능이 내장되어 있습니다.

  • bash: compgen -u데이터베이스에 있는 열거 가능한 사용자 목록을 반환합니다.
  • zsh: $userdirs사용자 이름을 홈 디렉토리에 매핑하는 연관 배열(열거 가능한 데이터베이스로 제한되지만, ~user열거 불가능한 데이터베이스의 사용자에 대해 확장하면 항목이 추가됩니다 $userdirs). 그래서 당신은 이것을 할 수 있습니다 :

    printf '%s => %s\n' "${(kv@)userdirs}"
    

    사용자와 해당 홈 디렉터리를 나열합니다.

    하지만 zsh상호작용할 때만 작동합니다..

  • tcsh, fish그리고 yash사용자 이름을 완성할 수 있는 세 가지 다른 셸(예: ~<Tab>인수 완성 시)이 있지만 프로그래밍 방식으로 사용자 이름 목록을 얻을 수 있는 것처럼 보이지는 않습니다.

답변2

사용자의 홈 디렉토리를 나열하는 더 좋은 방법은 사용자의 홈 디렉토리가 /etc/passwd어디에 있는지 가정하는 대신 구문 분석하고 추출하는 것입니다.

두 번째 의견에 따르면 실제로 홈 디렉토리가 아닌 사용자 이름이 필요합니다. 이 경우 /etc/passwd어쨌든 더 나은 옵션입니다. 일부 Linux/UNIX 시스템은 다른 사용자 인증 메커니즘(예: LDAP)으로 구성되므로 쿼리가 처음에 생각했던 것보다 더 복잡해지지만 이는 /etc/passwd좋은 출발점입니다.

답변3

짧은 답변:

compgen -u

보통 답변: 를 사용하고 있으므로 를 사용하여 bash가능한 모든 완성 항목을 나열할 수 있습니다 . 이것은 매우 일반적인 사용법이며 축약될 수 있습니다 . 쉘이 내장되어 있으므로 자체 매뉴얼 페이지가 없습니다. 대신에~compgen -A usercompgen -ucompgen큰 타격(1)문서를 받고 관련 부분을 읽으십시오.프로그래밍 가능한 완성.

보다 급진적인 대안

이식성에 깊은 관심을 갖고 있다면 다른 사람의 bash.

(getent passwd ||
    dscl . -ls /Users dsAttrTypeNative:homeDirectory || 
    nidump passwd  ||
    cat /etc/passwd) 2>/dev/null  |  cut -d: -f6

설명하다 긴 대답은 모든 것을 시도했기 때문에 최신 /etc/nsswitch.conf(GNU/Linux와 BSD 모두 함께 제공됨 getent), 기존 UNIX 암호 플랫 파일, MacOS의 디렉터리 서비스 1( dscl), 그리고 더 오래된 고양이 테마 버전의 MacOS X 및 NeXTSTEP( nidump)도 있습니다.

단순한 하지만 얼마나 휴대성이 좋아야 합니까? Unix에는 작업을 수행하는 방법이 다양하며 때로는 더 간단한 것만으로도 충분합니다. 둘 중 하나를 선택해야 한다면 getent passwd | cut -d: -f6쉘 스크립트를 사용하는 것이 좋습니다. ²


각주 1: 저는 더 이상 MacOS를 사용하지 않습니다. 따라서 누군가 제 구문이 올바른지(그리고 출력에 혼란스러운 콜론이 포함되어 있지 않은지) 확인하는 데 도움을 줄 수 있다면 cut좋을 것입니다 . 감사해요.

각주²: 내가 제안하는 것과 내가 하는 일은 다를 수 있습니다. 개인적으로 저는 cut -d: -f1 /etc/passwd명령줄에서 전통적인 방식을 더 자주 사용할 것입니다. 수십 년 동안 반복한 결과, 내 뇌가 다른 일을 하는 동안 내 손가락은 타이핑을 할 수 있게 되었습니다.

답변4

무엇에 대해 ls -l ~/..? 홈 디렉토리의 상위 디렉토리에 있는 모든 디렉토리를 나열합니다.

관련 정보