답변:
역사적으로 (최대 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
성공하고 디렉토리 목록을 얻습니다!
이것은 사실상 유닉스 초기부터 보류 된 기능이며 오랫동안 다루지 않은 기능입니다. 저의 일부는 이것이 이전 버전과의 호환성 이유로 인해 유지되고 있다고 의심하지만 실제로 아무것도 아프지 않기 때문에 아무도 기능을 제거하기에 충분히 신경 쓰지 않을 것입니다.
텍스트 파일 뷰어는 적고 cat 은 임의의 데이터를 복사하는 도구입니다. 그래서 적은 당신이 방대한 양의 데이터가 있거나 매우 이상하게 동작합니다 뭔가를 개방하지 않는 확인하기 위해 자체 검사를 수행합니다. 반면에, 고양이 는 그러한 검사를 전혀하지 않습니다. 커널이 어떤 것을 열 수 있다면 (파이프 나 장치이거나 더 나쁜 것이더라도), 고양이 는 그것을 읽을 것입니다.
그렇다면 왜 OS에서 cat 이 디렉토리를 열 수 있습니까? 전통적으로 BSD 스타일 시스템에서는 모든 디렉토리를 파일로 읽을 수 있었으며, 이는 디스크에 저장된 dirent 구조를 해석함으로써 프로그램이 디렉토리를 먼저 나열하는 방식이었습니다.
나중에 디스크 구조는 커널이 사용하는 dirent와 달라지기 시작했습니다. 이전에는 디렉토리가 선형 목록이었고 나중에 파일 시스템은 해시 테이블, B- 트리 등을 사용하기 시작했습니다. 따라서 디렉토리를 직접 읽는 것은 더 이상 간단하지 않았습니다. 커널은이를 위해 전용 기능을 확장했습니다. (주된 이유인지 또는 캐싱과 같은 다른 이유로 주로 추가되었는지 확실하지 않습니다.)
일부 BSD 시스템에서는 계속 읽기 위해 모든 디렉토리를 열 수 있습니다. 디스크에서 원시 데이터를 제공하는지 또는 에뮬레이트 된 dirent 목록을 대신 반환하는지 또는 파일 시스템 드라이버가 결정했는지 여부를 알 수 없습니다.
그래서 아마도 맥 OS 커널이 허용하는 운영 체제 중 하나 인 만큼 파일 시스템은 데이터를 제공합니다. 그리고 그 차이는 즉 /dev
에있는 devfs
동안, 초기에이를 수 있도록 작성된 파일 시스템을 /
현대에 불필요한으로이 기능을 생략 APFS 파일 시스템에 있습니다.
면책 조항 : 실제로 BSD 또는 macOS에 대한 연구는하지 않았습니다. 나는 단지 그것을 윙윙 거리고있다.
/etc
그렇게 할 것이라고 생각 했기 때문에 그것을 벤치 마크로 사용했습니다.
mount
또는 실행 위치 /sbin/mount
를 확인하십시오.
/dev
사용하여 가상 파일 시스템입니다 devfs
반면 드라이버 /etc
의 일부 /
사용하여 파일 시스템 apfs
드라이버를. 따라서 이유 cat
는 하나만 읽고 다른 것은 읽지 않고 드라이버 apfs
와 devfs
드라이버 의 차이점 입니다.
neofetch
정보에 대한 :) i.imgur.com/3azpnDt.png