리눅스에서의 파일 디스크립터와 리다이렉션
이 글은 리눅스에서의 파일 디스크립터와 이를 활용한 리다이렉션에 대해 소개한다.
1. 리눅스 표준 스트림 3가지와 파일 디스크립터
각 유닉스 프로세스는 아래 세 개의 표준 스트림에 대응되는 세 개의 POSIX 표준 파일 디스크립터를 갖는다.
파일 디스크립터란 C int
타입의 값이며 아래에서 소개할 파일 디스크립터 테이블의 index 번호이다.
표준 입력, 출력, 오류 스트림은 각 프로세스의 파일 디스크립터의 0, 1, 2번을 할당받는다.
Integer value | Name | symbolic constant | file stream |
---|---|---|---|
0 | Standard input | STDIN_FILENO | stdin |
1 | Standard output | STDOUT_FILENO | stdout |
2 | Standard error | STDERR_FILENO | stderr |
리눅스 셸에서의 Redirect는 기본적으로 파일에 쓰고, 파일에서 읽지만 파일 대신 파일 디스크립터를 사용하고, 파일 디스크립터 앞에 &
를 붙이면 그대로 적용된다.
예를 들어, command > 1
은 표준 출력으로 Redirect 하라는 의미가 아니라 파일 1
로 출력하라는 것으로 해석되며, command >& 1
는 파일 디스크립터 1이 가리키는 파일로 출력하라는 것으로 해석되며, 이는 표준 출력이므로, 정상적으로 출력됨을 확인할 수 있다.
참고로 command 2 >& 1
의 경우 표준 오류 스트림이 표준 출력 스트림으로 Redirect되는데 왜 2 앞에는 &
가 붙지 않아도 될까? 그 이유는…
& is only interpreted to mean “file descriptor” in the context of redirections
라고 한다. (나도 잘 모르겠다. 왜 2>
가 stderr를 Redirect 한다는 의미로 쓰일 수 있는지도 모르겠다. 이건 셸 문서를 봐야할듯.)
참고: StackOverFlow
2. 파일 디스크립터 테이블
Process마다 파일 디스크립터 테이블이 하나씩 존재한다. 파일 디스크립터는 index이므로 auto_increment
와 같이 1씩 증가하며 발급된다. (따라서 Process에서 처음 파일 디스크립터를 발급 받는 경우 3부터 시작한다.)
아래와 같은 함수들이 파일 디스크립터를 하나 생성한다. (<unistd.h>
에 정의돼있다.)
open()
creat()
socket()
accept()
네트워크 관련해서도 select()
, bind()
, listen()
, connect()
등 파일 디스크립터와 관련된 함수들이 많은데 아직 C/C++ 기반 TCP/IP 프로그래밍을 해보지 못해서 추후에 다루려고 한다.
3. 파일 디스크립터 조회 및 제한
ls -trn
명령으로 프로세스별 파일 디스크립터를 조회할 수 있다.
ulimit
명령으로 프로세스별 파일 디스크립터 개수의 제한 역시 조회할 수 있다.
이 명령은 또한 그 제한을 바꿀 수도 있는데, ulimit의 open files의 경우 65535까지 가능했다. (이를 초과해서는 root 권한으로도 할 수 없었다.)
리눅스에서의 파일 디스크립터와 리다이렉션