나는 이 유닉스 튜토리얼을 읽고이 인용문을 보았습니다 ...
여기서 디렉토리는 단지 특별한 유형의 파일이라는 점에 유의해야합니다.
...하지만 설명이나 세부 사항은 제공되지 않습니다. 디렉토리는 실제로 어떻게 파일입니까?
나는 이 유닉스 튜토리얼을 읽고이 인용문을 보았습니다 ...
여기서 디렉토리는 단지 특별한 유형의 파일이라는 점에 유의해야합니다.
...하지만 설명이나 세부 사항은 제공되지 않습니다. 디렉토리는 실제로 어떻게 파일입니까?
답변:
* nix 스타일 (및 기타) 운영 체제의 많은 엔티티는 파일 시스템에 저장된 일련의 바이트 일 필요는 없지만 파일로 간주되거나 정의 된 파일과 유사한 측면을 갖습니다. 디렉토리가 어떻게 구현되는지는 파일 시스템의 종류에 따라 다르지만 일반적으로 목록으로 간주되는 디렉토리는 저장된 바이트 시퀀스이므로 특별한 의미가 없습니다.
* nix 컨텍스트에서 "파일"이 무엇인지 정의하는 한 가지 방법은 파일 설명자 와 연관된 파일 디스크립터 라는 것입니다. Wikipedia 기사에 따르면 파일 설명자
파이프 또는 네트워크 연결과 같은 파일 또는 기타 입력 / 출력 리소스 에 액세스하는 데 사용되는 추상 표시기입니다 .
즉, 시퀀스의 소스 / 대상이 지정되지 않았더라도 바이트 시퀀스를 읽거나 쓸 수있는 다양한 종류의 리소스를 나타냅니다. 다시 말해, 자원의 "어디"는 무엇이든 될 수 있습니다. 그것을 정의하는 것은 그것이 정보의 도관이라는 것입니다. 이것은 때때로 유닉스에서 "모든 것이 파일"이라고 말하는 이유의 일부입니다. 문자 그대로 완전히 받아 들여서는 안되지만 진지하게 고려해야 할 가치가 있습니다. 디렉토리의 경우,이 정보는 디렉토리의 내용 및 구현 수준이 낮은 파일 시스템 내에서 디렉토리를 찾는 방법과 관련이 있습니다.
네이티브 C 코드에서는 파일 디스크립터와 표면적으로 연결되어 있지 않기 때문에 디렉토리는 이런 의미에서 특별합니다. POSIX API는 특별한 유형의 스트림 핸들을 사용 DIR*
합니다. 그러나이 유형에는 실제로 검색 할 수 있는 기본 설명자가 있습니다 . 디스크립터는 커널에 의해 관리되며 이들에 액세스하려면 항상 시스템 호출이 필요하므로 디스크립터의 또 다른 측면은 OS 커널에 의해 제어되는 도관이라는 것입니다. 이들은 0으로 시작하는 고유 한 (프로세스 당) 숫자를 갖습니다. 이는 일반적으로 표준 입력 스트림 의 설명자입니다 .
openat
, fstatat
등) 디렉토리를 참조 파일 디스크립터를 사용하는을.
fsync()
읽기 전용 (!) 디렉토리 fd를 사용할 수 있으며 잘 정의 된 효과가 있습니다 (특히, 지정된 디렉토리의 파일 작성 / 이름 바꾸기 / 삭제를 "쓰기의 이론적으로 필요한 단계"로 디스크에 동기화 함) 임시 파일로 바꾸고 원래의 관용구 이름을 바꿉니다).
유닉스 일을하는 방식 : 모든 것이 파일입니다.
디렉토리는 하나의 (많은) 유형의 특수 파일입니다. 데이터가 포함되어 있지 않습니다. 대신 디렉토리 내에 포함 된 모든 파일에 대한 포인터가 포함됩니다.
다른 유형의 특수 파일 :
그러나 "파일"로 간주되기 때문에 파일 ls
이름을 바꾸고 이름을 바꾸고 이동할 수 있으며 특수 파일 유형에 따라 데이터를주고받을 수 있습니다.
내 대답은 단순한 회상이지만 199x 빈티지 유닉스에서 많은 디렉토리가 파일이었으며 디스크상의 inode의 어딘가에 "디렉토리"로 표시되었습니다.
비슷한 디렉토리를 열고 open(".", O_RDONLY)
사용 가능한 파일 디스크립터를 다시 얻을 수 있습니다. /usr/include
올바른 C 구조체 정의를 찾아 내면 내용을 구문 분석 할 수 있습니다. 필자는 SunOS 4.1.x 시스템, SGI의 EFS 파일 시스템 및 파일 시스템에 대한 DEC의 Mips-CPU 워크 스테이션 (BSD4.2 FFS)에 대해이 작업을 수행했음을 알고 있습니다.
그것은 나쁜 경험이었습니다. 디렉토리가 더 이상 엄격한 파일이 아니더라도 가상 파일 시스템 계층에서 표준화하는 것은 이식성을 위해 좋은 것입니다. VFS 계층을 사용하면 ReiserFS 또는 NFS와 같이 디렉토리가 파일이 아닌 파일 시스템을 실험 할 수 있습니다.
cp --link dir1/* dir2
비록 dd에 의해 복사 된 디렉토리가 본질적으로에 해당한다면 그것의 유용성은 확실하지 않지만 매우 논리적이라고 생각합니다 .
리눅스 시스템은 범용 i / o 모델을 사용하기 때문에 디렉토리는 파일이다 . 모델에서 시스템의 모든 것은 파일이며 동일한 시스템 호출 및 다양한 명령으로 액세스 할 수 있습니다.
i- 노드에는 파일 유형에 대한 표시가 있고 파일 이름 테이블과 다른 i- 노드에 대한 링크가되는 특수 구조를 갖기 때문에 특수한 유형입니다. 디렉토리의 i- 노드에서 "하드 링크"라고도하는 이러한 파일 이름 링크 쌍은 디렉토리의 "내부"파일을 열거합니다.
디렉토리는 파일을 구성하기위한 것입니다. 파일이 디렉토리에서 다른 디렉토리로 "이동"되면 파일 자체는 디스크에서 재배치되지 않습니다. 한 디렉토리 i- 노드의 항목이 제거되고 다른 디렉토리 i- 노드에 기록됩니다.
허용 된 답변이 완전히 맞지 않습니다. POSIX 시스템에서 "노드"는 파일 및 디렉토리를 가리 킵니다. 파일 디스크립터는 시스템 전체가 아닌 프로세스에만 고유합니다. 그러나 하나 이상의 inode가 단일 파일을 가리킬 수 있지만 inode는 고유합니다. 허용 된 답변에 대해 의견을 말했지만 담당자 제한으로 인한 것은 아닙니다.
ls -l >test.txt;ln -vf test.txt test2.txt;ls -li test.txt test2.txt
. 따라서 하드 링크는 동일한 inode 번호를가집니다.
fork()
s 인 경우 자식 프로세스가 O_CLOEXEC
원래 프로세스와 정확히 같은 파일 설명자 엔터티를 가질 것입니다 (특별한 상황, 즉 플래그 제외 ). 또 다른 예 : 아파치 자식 프로세스는 listen()
동일한 소켓 파일 설명자에 있습니다. 그러나이 대답은 커널 내부 데이터 구조이며 커널 메모리에만 존재하는 파일 디스크립터에 관한 것이 아닙니다. 이 ( false ) 답변은 디렉토리 항목과 아이 노드에 관한 것으로 디스크상의 엔터티입니다 (즉, 하드 드라이브의 물리적 바이트 임).
fork()
자식 프로세스가 부모 프로세스 seek()
의 close()
파일 설명자에 영향을 미치지 않습니다. 따라서 파일 디스크립터는 부분적으로 프로세스 전용 구조라고 생각합니다. 그러나이 질문은 그들에 관한 것이 아니며,이 질문은 급류 / 아이디어에 관한 것이며이 질문에 대한 전적으로 잘못된 대답에 대해 당신을 논평하고 있습니다.