왜 고양이를 / dev 할 수 있습니까?


41

내가 할 수있는 cat /dev내가 할 수있는, ls /dev내가 할 수 없습니다 less /dev. 이 디렉토리 는 왜 cat허용하고 cat다른 디렉토리 는 허용 하지 않습니까?

zsh에서이 동작의 그림.


@KamilMaciorowski, 여기에 출력 그리고 neofetch정보에 대한 :) i.imgur.com/3azpnDt.png
haboutnnah

답변:


43

역사적으로 (최대 V7 UNIX 또는 약 1979 년) read시스템 호출은 파일과 디렉토리 모두에서 작동했습니다. read디렉토리에서 사용자 프로그램은 디렉토리 항목을 얻기 위해 구문 분석 할 간단한 데이터 구조를 리턴합니다. 실제로 V7 ls도구는 read디렉토리에서 정확하게 결과 데이터 구조를 구문 분석하고 구조화 된 목록 형식으로 출력합니다.

파일 시스템이 복잡 해짐에 따라이 "간단한"데이터 구조는 readdir프로그램의 출력을 구문 분석하는 데 도움이 되는 라이브러리 함수가 추가 된 시점까지 더욱 복잡해졌습니다 read(directory). 시스템과 파일 시스템에 따라 디스크 포맷이 다를 수 있으므로 복잡해졌습니다.

Sun은 NFS (Network File System)를 도입했을 때 온 디스크 디렉토리 구조를 완전히 추상화하려고했습니다. 그러나 read(directory)플랫폼에 독립적 인 디렉토리 표시를 반환하는 대신 새로운 시스템 호출을 추가하고 네트워크 마운트 디렉토리를 getdirents금지 read했습니다. 이 시스템 호출은 다양한 UNIX 풍미의 모든 디렉토리에서 작동하도록 신속하게 조정되어 디렉토리의 내용을 얻는 기본 방법이되었습니다. ( https://utcc.utoronto.ca/~cks/space/blog/unix/ReaddirHistory 에서 추상화 된 내역 )

때문에 readdir현재 디렉토리를 읽을 수있는 기본 방법입니다, read(directory)일반적으로 대부분의 최신 운영체제 (QNX, 예를 들어, 구현하는 주목할만한 예외에 (-EISDIR를 반환) 구현되지 않은 readdir것처럼 read(directory)). 그러나 대부분의 최신 커널에서 "가상 파일 시스템"디자인을 사용하면 디렉토리를 읽을 수 있는지 여부에 관계없이 개별 파일 시스템에 따라 다릅니다.

실제로 macOS devfs에서 /dev마운트 지점의 기본 파일 시스템은 실제로 읽기를 지원합니다 ( https://github.com/apple/darwin-xnu/blob/xnu-4570.1.46/bsd/miscfs/devfs/devfs_vnops.c#L629 ) :

static int
devfs_read(struct vnop_read_args *ap)
{
        devnode_t * dn_p = VTODN(ap->a_vp);

    switch (ap->a_vp->v_type) {
      case VDIR: {
          dn_p->dn_access = 1;

          return VNOP_READDIR(ap->a_vp, ap->a_uio, 0, NULL, NULL, ap->a_context);

READDIR읽기를 시도하면 명시 적으로 호출 합니다 /dev(아래의 파일 읽기 /dev는 별도의 함수-로 처리됨 devfsspec_read). 따라서 프로그램이 read시스템 호출 on을 호출하면 /dev성공하고 디렉토리 목록을 얻습니다!

이것은 사실상 유닉스 초기부터 보류 된 기능이며 오랫동안 다루지 않은 기능입니다. 저의 일부는 이것이 이전 버전과의 호환성 이유로 인해 유지되고 있다고 의심하지만 실제로 아무것도 아프지 않기 때문에 아무도 기능을 제거하기에 충분히 신경 쓰지 않을 것입니다.


아마도 후자는 대부분의 디렉토리에서 제거 된 것으로 보입니다.
user20574

36

텍스트 파일 뷰어는 적고 cat 은 임의의 데이터를 복사하는 도구입니다. 그래서 적은 당신이 방대한 양의 데이터가 있거나 매우 이상하게 동작합니다 뭔가를 개방하지 않는 확인하기 위해 자체 검사를 수행합니다. 반면에, 고양이 는 그러한 검사를 전혀하지 않습니다. 커널이 어떤 것을 열 수 있다면 (파이프 나 장치이거나 더 나쁜 것이더라도), 고양이 는 그것을 읽을 것입니다.

그렇다면 왜 OS에서 cat 이 디렉토리를 열 수 있습니까? 전통적으로 BSD 스타일 시스템에서는 모든 디렉토리를 파일로 읽을 수 있었으며, 이는 디스크에 저장된 dirent 구조를 해석함으로써 프로그램이 디렉토리를 먼저 나열하는 방식이었습니다.

나중에 디스크 구조는 커널이 사용하는 dirent와 달라지기 시작했습니다. 이전에는 디렉토리가 선형 목록이었고 나중에 파일 시스템은 해시 테이블, B- 트리 등을 사용하기 시작했습니다. 따라서 디렉토리를 직접 읽는 것은 더 이상 간단하지 않았습니다. 커널은이를 위해 전용 기능을 확장했습니다. (주된 이유인지 또는 캐싱과 같은 다른 이유로 주로 추가되었는지 확실하지 않습니다.)

일부 BSD 시스템에서는 계속 읽기 위해 모든 디렉토리를 열 수 있습니다. 디스크에서 원시 데이터를 제공하는지 또는 에뮬레이트 된 dirent 목록을 대신 반환하는지 또는 파일 시스템 드라이버가 결정했는지 여부를 알 수 없습니다.

그래서 아마도 맥 OS 커널이 허용하는 운영 체제 중 하나 인 만큼 파일 시스템은 데이터를 제공합니다. 그리고 그 차이는 즉 /dev에있는 devfs동안, 초기에이를 수 있도록 작성된 파일 시스템을 /현대에 불필요한으로이 기능을 생략 APFS 파일 시스템에 있습니다.

면책 조항 : 실제로 BSD 또는 macOS에 대한 연구는하지 않았습니다. 나는 단지 그것을 윙윙 거리고있다.


이것은 말이되는 것 같습니다. 표준 OS 파일 시스템과 다른 스토리지 섹션이 있습니까? 나는 /etc그렇게 할 것이라고 생각 했기 때문에 그것을 벤치 마크로 사용했습니다.
haboutnnah

2
반대로, 일반적으로 / etc는 일반 파일을 포함하는 일반 폴더입니다. 그러나 다른 가상 파일 시스템 이있을 있습니다. – 현재 마운트 된 위치 mount또는 실행 위치 /sbin/mount를 확인하십시오.
grawity

네가 옳아! 이 참조 i.imgur.com/pcVpo1o.png
haboutnnah

이건 정말 깔끔한 @grawity입니다 i.imgur.com/8QuR0FK.png
haboutnnah

6
@haboutnnah 귀하의 스크린 샷은 그 확인 /dev사용하여 가상 파일 시스템입니다 devfs반면 드라이버 /etc의 일부 /사용하여 파일 시스템 apfs드라이버를. 따라서 이유 cat는 하나만 읽고 다른 것은 읽지 않고 드라이버 apfsdevfs드라이버 의 차이점 입니다.
kasperd
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.