모든 사용자 이름 및 / 또는 홈 디렉토리를 어떻게 나열합니까?


16

컴퓨터의 모든 사용자 디렉토리를 나열하고 싶습니다.

ls -l /home

그러나 나는 다른 컴퓨터에 배포 될 스크립트에서 사용하며 어쩌면 집으로 부르지 않는 컴퓨터 (예 : myHome)에 사용합니다. 그래서 나는 그것을 일반화하고 싶습니다 ls -l ~. 그러나 모든 사용자의 홈 디렉토리 이름 대신 내 사용자의 홈 디렉토리를 나열합니다 (기본적으로 컴퓨터에서 사용자 이름 목록을 얻고 싶습니다). 일반화하려면 어떻게해야합니까?


19
사실이 모든 사용자의 홈 디렉토리의 하위 디렉토리이다 것이라는 보장은 어느 하나의 디렉토리.
hobbs

17
@hobbs 또는 사용자가 로그인 할 때까지 존재합니다. 이것은 실제로 매우 복잡한 복잡한 문제 중 하나입니다.
EightBitTony

11
~일반적으로 또는에 해당 /home/user하지 않는 /home또는 /home/*의도와 비슷 하다는 것을 명심하십시오 .
Ethan Kaminski

2
@EightBitTony : ... 나 홈 디렉토리가 있는지 어떤 보장이 전혀은 . 예를 들어, Ubuntu 설치에서을 포함한 여러 시스템 사용자 nobody는 홈 디렉토리가로 설정되어 /nonexistent있습니다. (물론, 해당 사용자는 암호 해시를 설정 *하고 쉘을 /usr/sbin/nologin또는로 설정 /bin/false했기 때문에 처음에는 정상적인 의미로 로그인 할 수 없습니다.)
Ilmari Karonen

1
반면, 구식 NFS 서버는 이름을 모르는 사용자를 위해 OS에 홈 디렉토리를 제공 할 수 있습니다.
rackandboneman

답변:


45

많은 시스템이이 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, fishyash(완료 할 때 예를 들어 사용자 이름을 완료 할 수있는 세 가지 다른 포탄입니다 ~<Tab>인수), 그러나 프로그래밍 사용자 이름의 목록을 얻을 수 있도록처럼은 보이지 않는다.


OP에 대한 도전은 getent거기에 갈지 여부를 알고있을 것입니다. 어떤 정도는 '기타 기계'의 범위에 달려 있다고 생각합니다.
EightBitTony

1
@EightBitTony, perl대안을 추가했습니다 .
Stéphane Chazelas

1
Mac에서는 아마도 Open Directory와 관련된 것일 수 있습니다.
SilverWolf-복원 모니카

@seaturtle perl -le 'while (@e = getpwent) {print $e[7]}'은 macOS에서 잘 작동합니다.
Stéphane Chazelas

1
@FloHe는 사용자 이름입니다. 유닉스 시스템의 대부분의 사용자는 시스템 서비스 실행에 전념하는 특수 시스템 사용자입니다. getent passwd사용자 데이터베이스를 보여줍니다. 첫 번째 필드는 사용자 이름이고 6 번째 필드는 사용자 홈 디렉토리입니다.
Stéphane Chazelas

17

사용자 홈 디렉토리를 나열하는 더 좋은 방법은 구문 분석하는 것입니다. /etc/passwd 및 추출하고 위치에 대한 가정을하지 않는 것입니다.

그리고 두 번째 의견으로 판단하면 실제로는 홈 디렉토리가 아닌 사용자 이름 /etc/passwd이 더 좋습니다. 일부 Linux / UNIX 시스템에는 다른 사용자 인증 메커니즘 (예 : LDAP)이 구성되어 있으므로 궁극적으로 쿼리는 처음 생각했던 것보다 복잡하지만 /etc/passwd시작하기에 좋은 곳입니다.


9
getent이를 지원하는 시스템을 참조하십시오 .
Kusalananda

6
예, getent파싱보다 항상 낫습니다 /etc/passwd(“다른 사용자 인증 메커니즘”의 문제를 해결합니다).
Stephen Kitt

@Kusalananda getent솔루션 의 문제점 은 특정 값을 쿼리하지 않고 데이터 소스를 열거 할 수 있다고 가정한다는 것입니다. Stéphane Chazelas 가이 질문에 대한 답변에 자세히 설명되어 있지만이 페이지를 감추고있는 사람에 대해서는 의견을 추가하고 싶습니다.
Andrew Henle

7

짧은 대답 :

compgen -u

중간 답변 : bash~사용 하고 있기 때문에을 (를) 사용할 수있는 모든 항목을 나열 할 수 있습니다 compgen -A user. 그것은 일반적인 사용법이며 축약 될 수 있습니다 compgen -u. 쉘 내장 compgen으로 자체 매뉴얼 페이지가 없습니다. 대신 설명서는 bash (1) 를 참조하고 프로그래밍 가능 완료 섹션을 읽으십시오 .

보다 철저한 대안

이식성이 매우 염려된다면을 가진 다른 컴퓨터에 의존하지 못할 수도 있습니다 bash. 이 경우 다음을 수행하십시오.

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

설명 은 상관없이 새로운 /etc/nsswitch.conf 파일을 (GNU / 리눅스와 BSD 모두가 함께 사용 여부, 거의 모든 UNIX 시스템에서 작동 할 수 있도록 긴 대답은, 모든 것을 시도 getent), 기존의 UNIX는 맥 OS의 플랫 파일은 passwd 디렉토리 서비스 ¹ ( dscl) 또는 심지어 고양이를 테마로 한 이전 MacOS X 릴리스 및 NeXTSTEP ( nidump).

단순성 그러나 얼마나 휴대해야합니까? 유닉스에는 여러 가지 방법이 있으며 때로는 더 간단한 방법이 있습니다. 하나를 선택해야한다면 getent passwd | cut -d: -f6쉘 스크립트를 추천 합니다 .²


각주 ¹ : MacOS를 조금도 사용하지 않았으므로 누군가 구문이 맞다는 것을 확인할 수 있다면 (그리고 출력에 엉망이되는 길 잃은 콜론이 포함되어 있지 않음 cut) 훌륭합니다. 감사.

각주 ² : 내가 추천하는 것과하는 것이 다를 수 있습니다. 개인적으로, 나는 종종 cut -d: -f1 /etc/passwd커맨드 라인에서 전통적인 것을 사용할 것 입니다. 수십 년간 반복 한 후에, 내 마음이 다른 일을하는 동안 내 손가락이 입력 할 수 있습니다.


2
모든 Mac OS X 컴퓨터는 시스템과 함께 제공되므로 배쉬가 거의 보장됩니다. (zsh와 다른 쉘들도
마찬가지

사실 MacOS를 사용했을 때 Apple은 오랫동안 bash를 업데이트하지 않았으며 항상 교체 해야하는 지저분한 버전 3이었습니다. Apple은 bash 업데이트에 대해 더 잘 알고 있습니까?
hackerb9


사실은 생각하지 않았습니다. 내 bash 버전 (macOS Sierra 10.12.6)은 3.2.57입니다. (:
SilverWolf-복원 모니카

어쨌든, bash이 있었다 compgen -u2.04는 2000 년 출시 이후
스테판 Chazelas가를

2

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


4
그것은 모든 홈 디렉토리가 동일한 디렉토리에 기반을 둔 시스템에서만 작동합니다. 많지 않습니다 ( /home리눅스 시스템에서는 일반적 이라고 생각할 수 있지만 그것을 root? 로 실행할 때 어떤 일이 발생 합니까?) 홈 디렉토리를 나열하는 것은 당신이 겪을 가능성이있는 모든 사례를 다루고 싶다면 함정으로 가득 찬 모험입니다. 자세한 내용은 다른 답변을 참조하십시오.
Stephen Kitt

7
이것은 OP의 인식 된 문제에 직접 대답하는 유일한 대답 일 것 입니다. 그러나 OP의 근본적인 문제에 대한 답변은 아닙니다 .
파이프

1
이 답변의 가치는 그것이 무엇을 놓치고 있는지, 왜 다른 고득점 답변만큼 좋지 않은지를 이해하는 데 있습니다.
Criggie
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.