모든 사용자 이름 및 / 또는 홈 디렉토리를 어떻게 나열합니까? 나는 그것을 일반화하고 싶습니다

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

ls -l /home

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



답변

많은 시스템이이 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>인수), 그러나 프로그래밍 사용자 이름의 목록을 얻을 수 있도록처럼은 보이지 않는다.


답변

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

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


답변

짧은 대답 :

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커맨드 라인에서 전통적인 것을 사용할 것 입니다. 수십 년간 반복 한 후에, 내 마음이 다른 일을하는 동안 내 손가락이 입력 할 수 있습니다.


답변

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


답변