간단한 용어로 설명되는 파일 디스크립터 란 무엇입니까?


383
  1. 위키 백과에 비해 파일 디스크립터에 대한 더 간단한 설명은 무엇입니까? 왜 필요한가요? 예를 들어 쉘 프로세스를 예로 들어 어떻게 적용합니까?

  2. 프로세스 테이블에 둘 이상의 파일 디스크립터가 있습니다. 그렇다면 왜 그렇습니까?


3
stdin stdout stderr 등의 개념은 어떻습니까? 브라우저 프로세스가 열리고 html을 표시하기 위해 임시 파일을 열었습니다. 프로세스는 동일한 fd를 사용하여 읽기 / 쓰기? 또한 프로세스 테이블 ..... fd0 포인터와 같은 항목이 있습니다. fd1 포인터 fd2 포인터 .....이 모든 파일이 RAM에 있음을 의미합니까? 왜 다른 포인터?
Nishant

43
파일을 열면 OS는 해당 파일에 스트림을 생성하고 해당 스트림을 열린 파일에 연결합니다. 실제로 디스크립터는 해당 스트림을 나타냅니다. 마찬가지로 OS에 의해 생성 된 기본 스트림이 있습니다. 이 스트림은 파일 대신 터미널에 연결됩니다. 따라서 터미널에 무언가를 쓰면 stdin 스트림과 OS로 이동합니다. 그리고 터미널에서 "ls"명령을 쓰면 OS가 stdout 스트림에 출력을 씁니다. stdout 스트림이 모니터 터미널에 연결되어 출력을 볼 수 있습니다.
Tayyab

1
브라우저 예제와 관련하여 브라우저가 파일을 열어 둘 필요는 없습니다. 브라우저 구현에 따라 다르지만 대부분의 경우 브라우저는 임시 파일을 열고 파일을 쓰고 파일을 닫습니다. 따라서 웹 페이지가 열려 있어도 파일을 열 필요는 없습니다. 디스크립터는 파일의 정보 만 보유하며 반드시 파일을 RAM에 보관하지 않아도됩니다. 디스크립터에서 데이터를 읽을 때 OS는 하드 디스크에서 데이터를 읽습니다. 파일 디스크립터의 정보는 하드 디스크 등에서 파일의 위치를 ​​나타냅니다.
Tayyab

5
파일 대 파일 설명자는 일대일 맵핑이 아닙니다. 같은 파일을 4 번 열고 (4) 다른 파일 설명자를 얻을 수 있습니다. 각각은 읽기, 쓰기 또는 둘 다에 사용될 수 있습니다 (open ()에 전달 된 플래그에 따라). 파일이 RAM 또는 디스크에 있는지 여부에 관계없이 커널과 다양한 캐시에 의해 숨겨집니다. 궁극적으로 캐시는 디스크에있는 것과 일치하며 (쓰기 용) 커널은 데이터가 캐시에 이미있는 경우 읽기 위해 디스크로 돌아 가지 않습니다.
Beano

7
이것은 쉽게 이해할 수있는 좋은 기사입니다. bottomupcs.com/file_descriptors.xhtml
Krishan Gopal

답변:


561

간단히 말해서, 파일을 열면 운영 체제는 해당 파일을 나타내는 항목을 작성하고 열린 파일에 대한 정보를 저장합니다. 따라서 OS에 100 개의 파일이 열려 있으면 OS (커널의 어딘가)에 100 개의 항목이 있습니다. 이 항목은 (... 100, 101, 102 ....)와 같은 정수로 표시됩니다. 이 항목 번호는 파일 설명자입니다. 따라서 운영 체제에서 열린 파일을 고유하게 나타내는 정수입니다. 프로세스가 10 개의 파일을 열면 프로세스 테이블에 파일 디스크립터에 대한 10 개의 항목이 있습니다.

마찬가지로 네트워크 소켓을 열면 해당 소켓도 정수로 표시되며 소켓 설명 자라고합니다. 난 당신이 이해 바랍니다.


7
또한 많은 파일을 한 번에 열면 파일 디스크립터가 부족할 수 있습니다. * nix 시스템은 디스크립터를 항상 열어 놓기 때문에 실행을 방해 /proc합니다.
Spencer Rathbun

8
@ ErbenMo : 아니오 동일하지 않을 수 있습니다. 파일을 열면 운영 체제에서 사용 가능한 FD를 할당하고 닫을 때 OS에서 FD를 해제하고 그 이후에 열린 다른 파일에 해당 FD를 할당 할 수 있습니다. 운영 체제가 열린 파일을 추적하는 방법이며 특정 파일과 관련이 없습니다.
Tayyab

49
" 운영 체제에서 열린 파일을 고유하게 나타내는 정수일뿐입니다. "이것은 잘못된 것입니다. 이 정수 는 프로세스 내에서 열린 파일을 고유하게 나타냅니다 . 예를 들어 파일 디스크립터 0은 한 프로세스에서 열린 파일 하나와 다른 프로세스에서 완전히 다른 열린 파일을 나타냅니다.
Keith Thompson

15
@Tayyab : 당신이 착각했다고 생각합니다. 파일 디스크립터 0, 1 및 2는 실행중인 프로세스의 표준 입력, 표준 출력 및 표준 오류입니다 . open()실행중인 다른 프로세스에 파일 디스크립터 3이있는 경우에도 파일 디스크립터 3 을 성공적으로 호출 하면 파일 디스크립터 3이 제공됩니다 . POSIX 정의는open() 다음을 참조하십시오 . 해당 프로세스에 대해 파일 디스크립터가 현재 열려 있지 않습니다 . " (강조 추가).
Keith Thompson

17
@ KeithThompson : 네 맞습니다. 실제로 추상화 수준에 관한 것입니다. 실제로 두 개의 테이블이 유지되는데, 첫 번째 테이블은 프로세스 당이고 두 번째 테이블은 시스템 전체입니다. 프로세스 별 테이블 (예 : fdtable)의 FD는 시스템 전체에 고유하지 않습니다. 그러나 시스템 전체 고유 항목을 포함하는 v- 노드 테이블에 맵핑됩니다. 따라서 fopen () 및 fileno () 함수를 호출하여 설명자를 확인하면 프로세스 당 fdtable의 인덱스를 반환하므로 두 가지 다른 프로세스에서 동일한 FD 번호를 얻을 수 있습니다. 그것을 가져 주셔서 감사합니다!
Tayyab

116

파일 디스크립터는 파일과 소켓 자원을 식별하기 위해 사용자와 커널 공간 사이의 인터페이스에서 사용되는 불투명 한 핸들입니다. 따라서 open()또는 socket()(커널에 인터페이스하기위한 시스템 호출)을 사용 하면 파일 설명자가 정수입니다 (실제로는 프로세스 u 구조의 색인이지만 중요하지는 않습니다). 당신이 시스템 호출을 사용하여 커널에 직접 인터페이스하려는 경우 따라서 read(), write(), close()등을 사용하는 핸들은 파일 설명이다.

stdio인터페이스 인 시스템 호출에 중첩 된 추상화 계층이 있습니다. 기본 시스템 호출보다 더 많은 기능 / 기능을 제공합니다. 이 인터페이스의 경우, 불투명 한 핸들은이며 호출에 FILE*의해 반환됩니다 fopen(). 사용에 많은 많은 기능이 있습니다 stdio인터페이스는 fprintf(), fscanf(), fclose(),, 여러분의 인생을 더 쉽게 존재하게되는. C에서 stdin, stdout그리고 stderr있습니다 FILE*, UNIX에서 각각 파일 설명에 매핑하는 0, 1하고 2.


6
개인적으로이 답변이 답변으로 표시된 답변보다 낫다고 생각합니다. 공감.
Tarik

101

말의 입에서 들으십시오 : APUE (Richard Stevens).
커널은 열려있는 모든 파일을 파일 디스크립터가 참조합니다. 파일 디스크립터는 음수가 아닌 숫자입니다.

기존 파일을 열거 나 새 파일을 만들면 커널은 파일 디스크립터를 프로세스에 반환합니다. 커널은 사용중인 모든 열린 파일 디스크립터의 테이블을 유지 보수합니다. 파일 디스크립터의 할당은 일반적으로 순차적이며 사용 가능한 파일 디스크립터 풀에서 다음 사용 가능한 파일 디스크립터로 파일에 할당됩니다. 파일을 닫으면 파일 디스크립터가 해제되어 추가 할당이 가능합니다.
자세한 내용은이 이미지를 참조하십시오.

두 프로세스

파일을 읽거나 쓰려고 할 때 open () 또는 create () 함수 호출에 의해 리턴 된 파일 디스크립터를 사용하여 파일을 식별하여 read () 또는 write () 의 인수로 사용하십시오 .
일반적으로 UNIX 시스템 쉘은 파일 디스크립터 0을 프로세스의 표준 입력 과 연관시키고 , 파일 디스크립터 1을 표준 출력 과, 파일 디스크립터 2를 표준 오류 와 연관시킵니다 .
파일 디스크립터의 범위는 0에서 OPEN_MAX입니다. 로 파일 디스크립터 최대 값을 얻을 수 있습니다 ulimit -n. 자세한 내용은 APUE Book 3 장을 참조하십시오.


1
0, 1, 2는 프로세스의 "stdin", "stdout"및 "stderr"과 연관되어 있으므로 다른 프로세스에 대해 동시에 해당 설명자를 사용할 수 있습니까?
Tarik

@Tarik : 파일 디스크립터는 프로세스 당입니다. 이것을 보려면 osquery를 다운로드 osqueryi <<< echo '.all process_open_files'하고 bash 쉘에서 실행 하십시오 .
벤 Creasy

29

다른 답변은 훌륭한 것들을 추가했습니다. 2 센트 만 추가하겠습니다.

Wikipedia에 따르면 파일 디스크립터는 음이 아닌 정수입니다. 내가 놓친 것 중 가장 중요한 것은 다음과 같이 말하는 것입니다.

파일 디스크립터는 프로세스 ID에 바인드됩니다.

우리는 가장 유명한 파일 디스크립터가 0, 1 및 2라는 것을 알고 있습니다. 0은 STDIN, 1에서 STDOUT, 2에서에 해당 STDERR합니다.

예를 들어 쉘 프로세스를 예로 들어 어떻게 적용합니까?

이 코드를 확인하십시오

#>sleep 1000 &
[12] 14726

ID가 14726 (PID) 인 프로세스를 작성했습니다. 를 사용하면 다음 lsof -p 14726과 같은 것을 얻을 수 있습니다.

COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
sleep   14726 root  cwd    DIR    8,1     4096 1201140 /home/x
sleep   14726 root  rtd    DIR    8,1     4096       2 /
sleep   14726 root  txt    REG    8,1    35000  786587 /bin/sleep
sleep   14726 root  mem    REG    8,1 11864720 1186503 /usr/lib/locale/locale-archive
sleep   14726 root  mem    REG    8,1  2030544  137184 /lib/x86_64-linux-gnu/libc-2.27.so
sleep   14726 root  mem    REG    8,1   170960  137156 /lib/x86_64-linux-gnu/ld-2.27.so
sleep   14726 root    0u   CHR  136,6      0t0       9 /dev/pts/6
sleep   14726 root    1u   CHR  136,6      0t0       9 /dev/pts/6
sleep   14726 root    2u   CHR  136,6      0t0       9 /dev/pts/6

네 번째 열 FD와 바로 다음 열 TYPE은 파일 디스크립터 및 파일 디스크립터 유형에 해당합니다.

FD의 일부 값은 다음과 같습니다.

cwd – Current Working Directory
txt – Text file
mem – Memory mapped file
mmap – Memory mapped device

그러나 실제 파일 설명자는 다음과 같습니다.

NUMBER – Represent the actual file descriptor. 

숫자 다음의 문자, 즉 "1u"는 파일을 여는 모드를 나타냅니다. r은 읽기, w는 쓰기, u는 읽기 및 쓰기입니다.

TYPE은 파일 유형을 지정합니다. TYPE 값 중 일부는 다음과 같습니다.

REG – Regular File
DIR – Directory
FIFO – First In First Out

그러나 모든 파일 디스크립터는 CHR – 문자 특수 파일 (또는 문자 장치 파일)입니다.

이제, 우리는 용 파일 디스크립터를 식별 할 수 있습니다 STDIN, STDOUT그리고 STDERR쉽게 lsof -p PID, 또는 우리는 우리의 경우 동일하게 볼 수 있습니다 ls /proc/PID/fd.

커널이 추적하는 파일 디스크립터 테이블은 파일 테이블 또는 inodes 테이블과 동일하지 않습니다. 다른 답변이 설명했듯이 이들은 별개입니다.

fd 테이블

이러한 파일 디스크립터가 실제로 어디에 있는지 /dev/pts/6, 예를 들어 저장된 것이 무엇인지 스스로에게 물어볼 수 있습니다.

sleep   14726 root    0u   CHR  136,6      0t0       9 /dev/pts/6
sleep   14726 root    1u   CHR  136,6      0t0       9 /dev/pts/6
sleep   14726 root    2u   CHR  136,6      0t0       9 /dev/pts/6

글쎄, /dev/pts/6순전히 기억 속에 산다. 이들은 일반 파일이 아니라 문자 장치 파일 이라고 합니다 . 당신은 이것을 확인할 수 있습니다 : ls -l /dev/pts/6그리고 그들은 c내 경우에 시작 crw--w----합니다.

OS와 같은 대부분의 Linux는 7 가지 유형의 파일을 정의합니다.

  • 일반 파일
  • 디렉토리
  • 캐릭터 장치 파일
  • 장치 파일 차단
  • 로컬 도메인 소켓
  • 명명 된 파이프 (FIFO) 및
  • 심볼릭 링크

1
감사. 실제로 프로세스 당임을 지적하는 것이 중요합니다! 사물을 더 잘 시각화하는 데 도움이됩니다.
Nishant

1
OS에서 정의한 파일 형식은 답변에서 언급 한 바와 같이 파일을보다 낮은 수준에서 이해하는 데 실제로 도움이됩니다.
Rohan Bhale

20

더 많은 포인트 File Descriptor:

  1. File Descriptors (FD)는 음이 아닌 정수입니다 (0, 1, 2, ...) 는 열린 파일과 연관된 입니다.

  2. 0, 1, 2표준 FD는 '해당 대응을이야 STDIN_FILENO, STDOUT_FILENO하고 STDERR_FILENO(정의 unistd.h) 쉘 프로그램이 시작 대신에 기본적으로 열었습니다.

  3. FD는 순차적 인 순서로 할당되므로 할당되지 않은 가장 낮은 정수 값을 의미합니다.

  4. 특정 프로세스에 대한 FD /proc/$pid/fd는 Unix 기반 시스템 에서 볼 수 있습니다 .


16

다른 답변 외에도 유닉스는 모든 것을 파일 시스템으로 간주합니다. 키보드는 커널 관점에서만 읽을 수있는 파일입니다. 화면은 쓰기 전용 파일입니다. 마찬가지로 폴더, 입 / 출력 장치 등도 파일로 간주됩니다. 파일이 열릴 때마다, 장치 드라이버 [장치 파일 용]가 open ()을 요청하거나 프로세스가 사용자 파일을 열 때 커널은 파일 디스크립터를 할당합니다. , 쓰기 전용 등 [참조 : https://en.wikipedia.org/wiki/Everything_is_a_file ]


파일 디스크립터는 익명 파이프 및 네트워크 소켓과 같이 파일 시스템에 존재하지 않는 것을 나타낼 수도 있습니다.
kbolino

12

파일 디스크립터 (FD) :

  • 에서 리눅스 / 유닉스 , 모든 파일입니다. 일반 파일, 디렉토리 및 장치는 파일입니다. 모든 파일에는 파일 설명자 (FD)라는 관련 번호가 있습니다.
  • 화면에는 파일 설명자가 있습니다. 프로그램이 실행되면 출력이 화면의 File Descriptor로 전송되고 모니터에 프로그램 출력이 표시됩니다. 출력이 프린터의 파일 디스크립터로 전송되면 프로그램 출력이 인쇄 된 것입니다.

    오류 리디렉션 :
    터미널에서 프로그램 / 명령을 실행할 때마다 항상 3 개의 파일이 열립니다
    1. 표준 입력
    2. 표준 출력
    3. 표준 에러.

    이 파일들은 프로그램이 실행될 때마다 항상 존재합니다. 파일 디스크립터 앞에서 설명한대로 각 파일과 연관됩니다.
    파일                                        파일 디스크립터
    표준 입력 STDIN 0
    표준 출력 STDOUT 1
    표준 오류 STDERR 2

  • 예를 들어 파일을 검색하는 동안 일반적으로 권한 거부 오류 또는 다른 종류의 오류가 발생합니다. 이러한 오류는 특정 파일에 저장할 수 있습니다.
    실시 예 1

$ ls mydir 2> errorsfile.txt

표준 오류에 대한 파일 디스크립터는 2입니다.
mydir이라는 이름의 디렉토리가 없으면
"2>"를 사용하여 명령 출력이 errorfile.txt 파일에 저장됩니다. "2>"를 사용하여 오류 출력을 "errorfile"파일로 리디렉션합니다. txt "
따라서, 프로그램 출력은 오류로 어수선하지 않습니다.

나는 당신이 당신의 대답을 얻었기를 바랍니다.


5

p1, p2, p3과 같은 모든 운영 체제에 프로세스 (p)가 실행 중입니다. 등 입니다. 각 프로세스는 일반적으로 파일을 지속적으로 사용합니다.

각 프로세스는 프로세스 트리 (또는 다른 표현의 프로세스 테이블)로 구성됩니다.

일반적으로, 운영 체제는 대표 각 프로세스의 각 파일에 바이 (각 프로세스 트리 / 테이블에서 말을하는 것입니다).

프로세스에서 사용 된 첫 번째 파일은 file0 이고, 두 번째는 file1 이고, 세 번째는 file2입니다. 입니다.

그러한 번호는 파일 디스크립터입니다.

파일 디스크립터는 일반적으로 정수 (0, 1, 2이며 0.5, 1.5, 2.5가 아님)입니다.

프로세스를 "프로세스 테이블"로 설명하고 테이블에 행 (항목)이 있다고 가정하면 각 항목의 파일 디스크립터 셀이 전체 항목을 나타내는 데 사용된다고 말할 수 있습니다.

비슷한 방식으로 네트워크 소켓을 열면 소켓 설명자가 있습니다.

일부 운영 체제에서는 파일 설명자가 부족할 수 있지만 이러한 경우는 극히 드물기 때문에 일반 컴퓨터 사용자는 걱정할 필요가 없습니다.

파일 디스크립터는 전역적일 수 있습니다 (프로세스 A는 0에서 시작하여 1에서 끝나고; 프로세스 B는 2에서 시작하고 3에서 종료됩니다). 디스크립터는 전역 적이 지 않으며 실제로 프로세스마다 다릅니다 (프로세스 A는 0에서 시작하여 5에서 끝나고 프로세스 B는 0에서 시작하고 10에서 종료됩니다).


Linux의 FD에 대한 자세한 내용은 다음을 참조

1
큰 답변 :)
humble_wolf

5

파일 기술자

  • 커널에 열려있는 모든 파일은 파일 디스크립터가 참조합니다.
  • 파일 디스크립터는 음수가 아닌 정수입니다.
  • 기존 파일을 열거 나 새 파일을 만들면 커널은 파일 디스크립터를 프로세스에 반환합니다.
  • 파일을 읽거나 쓰려고 할 때, 우리는 open 또는 create에 의해 재조정 된 파일 디스크립터가있는 파일을 읽거나 쓰는 인수로 식별합니다.
  • 각 UNIX 프로세스에는 20 개의 파일 디스크립터가 있으며 0에서 19까지 번호가 매겨 지지만 많은 시스템에서 63으로 확장되었습니다.
  • 프로세스가 시작될 때 처음 세 개는 이미 열려 있습니다. 0 : 표준 입력 1 : 표준 출력 2 : 표준 오류 출력
  • 부모 프로세스가 프로세스를 분기하면 자식 프로세스는 부모의 파일 설명자를 상속합니다.

1

모든 단순화 된 응답 위에 추가.
bash 스크립트에서 파일로 작업하는 경우 파일 설명자를 사용하는 것이 좋습니다.
예를 들면 다음과 같습니다.-
"test.txt"파일을 읽고 쓸 수 있습니다.
아래와 같이 파일 디스크립터를 사용하십시오

FILE=$1 # give the name of file in the command line
exec 5<>$FILE # '5' here act as the file descriptor
# Reading from the file line by line using file descriptor
while read LINE; do
    echo "$LINE"
done <&5

# Writing to the file using descriptor
echo "Adding the date: `date`" >&5 
exec 5<&- # Closing a file descriptor

-5

파일 디스크립터는 파일의 디스크립터입니다. 파일에 대한 링크를 제공합니다. 그들의 도움으로 파일을 읽고 쓰고 열 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.