위키 백과에 비해 파일 디스크립터에 대한 더 간단한 설명은 무엇입니까? 왜 필요한가요? 예를 들어 쉘 프로세스를 예로 들어 어떻게 적용합니까?
프로세스 테이블에 둘 이상의 파일 디스크립터가 있습니다. 그렇다면 왜 그렇습니까?
위키 백과에 비해 파일 디스크립터에 대한 더 간단한 설명은 무엇입니까? 왜 필요한가요? 예를 들어 쉘 프로세스를 예로 들어 어떻게 적용합니까?
프로세스 테이블에 둘 이상의 파일 디스크립터가 있습니다. 그렇다면 왜 그렇습니까?
답변:
간단히 말해서, 파일을 열면 운영 체제는 해당 파일을 나타내는 항목을 작성하고 열린 파일에 대한 정보를 저장합니다. 따라서 OS에 100 개의 파일이 열려 있으면 OS (커널의 어딘가)에 100 개의 항목이 있습니다. 이 항목은 (... 100, 101, 102 ....)와 같은 정수로 표시됩니다. 이 항목 번호는 파일 설명자입니다. 따라서 운영 체제에서 열린 파일을 고유하게 나타내는 정수입니다. 프로세스가 10 개의 파일을 열면 프로세스 테이블에 파일 디스크립터에 대한 10 개의 항목이 있습니다.
마찬가지로 네트워크 소켓을 열면 해당 소켓도 정수로 표시되며 소켓 설명 자라고합니다. 난 당신이 이해 바랍니다.
/proc
합니다.
open()
실행중인 다른 프로세스에 파일 디스크립터 3이있는 경우에도 파일 디스크립터 3 을 성공적으로 호출 하면 파일 디스크립터 3이 제공됩니다 . POSIX 정의는open()
다음을 참조하십시오 . 해당 프로세스에 대해 파일 디스크립터가 현재 열려 있지 않습니다 . " (강조 추가).
파일 디스크립터는 파일과 소켓 자원을 식별하기 위해 사용자와 커널 공간 사이의 인터페이스에서 사용되는 불투명 한 핸들입니다. 따라서 open()
또는 socket()
(커널에 인터페이스하기위한 시스템 호출)을 사용 하면 파일 설명자가 정수입니다 (실제로는 프로세스 u 구조의 색인이지만 중요하지는 않습니다). 당신이 시스템 호출을 사용하여 커널에 직접 인터페이스하려는 경우 따라서 read()
, write()
, close()
등을 사용하는 핸들은 파일 설명이다.
stdio
인터페이스 인 시스템 호출에 중첩 된 추상화 계층이 있습니다. 기본 시스템 호출보다 더 많은 기능 / 기능을 제공합니다. 이 인터페이스의 경우, 불투명 한 핸들은이며 호출에 FILE*
의해 반환됩니다 fopen()
. 사용에 많은 많은 기능이 있습니다 stdio
인터페이스는 fprintf()
, fscanf()
, fclose()
,, 여러분의 인생을 더 쉽게 존재하게되는. C에서 stdin
, stdout
그리고 stderr
있습니다 FILE*
, UNIX에서 각각 파일 설명에 매핑하는 0
, 1
하고 2
.
말의 입에서 들으십시오 : APUE (Richard Stevens).
커널은 열려있는 모든 파일을 파일 디스크립터가 참조합니다. 파일 디스크립터는 음수가 아닌 숫자입니다.
기존 파일을 열거 나 새 파일을 만들면 커널은 파일 디스크립터를 프로세스에 반환합니다. 커널은 사용중인 모든 열린 파일 디스크립터의 테이블을 유지 보수합니다. 파일 디스크립터의 할당은 일반적으로 순차적이며 사용 가능한 파일 디스크립터 풀에서 다음 사용 가능한 파일 디스크립터로 파일에 할당됩니다. 파일을 닫으면 파일 디스크립터가 해제되어 추가 할당이 가능합니다.
자세한 내용은이 이미지를 참조하십시오.
파일을 읽거나 쓰려고 할 때 open () 또는 create () 함수 호출에 의해 리턴 된 파일 디스크립터를 사용하여 파일을 식별하여 read () 또는 write () 의 인수로 사용하십시오 .
일반적으로 UNIX 시스템 쉘은 파일 디스크립터 0을 프로세스의 표준 입력 과 연관시키고 , 파일 디스크립터 1을 표준 출력 과, 파일 디스크립터 2를 표준 오류 와 연관시킵니다 .
파일 디스크립터의 범위는 0에서 OPEN_MAX입니다. 로 파일 디스크립터 최대 값을 얻을 수 있습니다 ulimit -n
. 자세한 내용은 APUE Book 3 장을 참조하십시오.
다른 답변은 훌륭한 것들을 추가했습니다. 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 테이블과 동일하지 않습니다. 다른 답변이 설명했듯이 이들은 별개입니다.
이러한 파일 디스크립터가 실제로 어디에 있는지 /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 가지 유형의 파일을 정의합니다.
더 많은 포인트 File Descriptor
:
File Descriptors
(FD)는 음이 아닌 정수입니다 (0, 1, 2, ...)
는 열린 파일과 연관된 입니다.
0, 1, 2
표준 FD는 '해당 대응을이야 STDIN_FILENO
, STDOUT_FILENO
하고 STDERR_FILENO
(정의 unistd.h
) 쉘 프로그램이 시작 대신에 기본적으로 열었습니다.
FD는 순차적 인 순서로 할당되므로 할당되지 않은 가장 낮은 정수 값을 의미합니다.
특정 프로세스에 대한 FD /proc/$pid/fd
는 Unix 기반 시스템 에서 볼 수 있습니다 .
다른 답변 외에도 유닉스는 모든 것을 파일 시스템으로 간주합니다. 키보드는 커널 관점에서만 읽을 수있는 파일입니다. 화면은 쓰기 전용 파일입니다. 마찬가지로 폴더, 입 / 출력 장치 등도 파일로 간주됩니다. 파일이 열릴 때마다, 장치 드라이버 [장치 파일 용]가 open ()을 요청하거나 프로세스가 사용자 파일을 열 때 커널은 파일 디스크립터를 할당합니다. , 쓰기 전용 등 [참조 : https://en.wikipedia.org/wiki/Everything_is_a_file ]
파일 디스크립터 (FD) :
$ ls mydir 2> errorsfile.txt
표준 오류에 대한 파일 디스크립터는 2입니다.
mydir이라는 이름의 디렉토리가 없으면
"2>"를 사용하여 명령 출력이 errorfile.txt 파일에 저장됩니다. "2>"를 사용하여 오류 출력을 "errorfile"파일로 리디렉션합니다. txt "
따라서, 프로그램 출력은 오류로 어수선하지 않습니다.
나는 당신이 당신의 대답을 얻었기를 바랍니다.
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에서 종료됩니다).
모든 단순화 된 응답 위에 추가.
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