standard stream 


standard stream은 컴퓨터 프로그램과 터미널 사이에 미리 연결되어진 I/O communication channel을 의미하는데,


standard input(stdin), standard output(stdout), standard error(stderr)가 존재한다. stdin의 경우 input device(key


board)로부터 들어오는 텍스트들이 프로그램으로 들어오는 채널을 의미하며 stdout의 경우 프로그램으로부터 나가는


텍스트들이 output device(display)로 들어오는 채널을 의미한다.



또한 각각의 standard stream마다 이에 대응되는 file descriptor들이 존재하는데, stdin에 대응되는 file descripter는


integer value 0이며 stdout은 1, stderr는 2에 해당된다. 프로세스가 시작될 때에는 자신의 부모 프로세스의 standard


stream들을 상속받으며, standard stream들과 대응되는 각각의 file descriptor들은 기본적으로 터미널을 가리키고 


있는 상태이다. (keyboard, display, ..)





위의 그림에서 현재 쉘은 2612라는 PID를 가지고 있는데, 이 PID의 fd들을 조사해보면 0,1,2가 /dev/pts10 을 가리


키고 있다. pts는 pseudo terminal slave의 약자로, 이는 내가 사용중인 터미널이 실제 터미널이 아니라 터미널을


emulate한 terminal emulator이기 때문이다.(xterm, gnome-terminal 등)



커널은 각각의 프로세스들마다 file descriptor table을 가지고 있으며, file descriptor는 file descriptor table의 inde


x로 사용된다. 프로세스가 시작될 때에는 기본적으로 file descriptor 0,1,2을 가지고 있는 상태로 시작된다.


file descriptor table은 프로세스가 사용중인 파일을 관리하기 위해 사용되는 테이블이며, 여기에는 file table에 대한


포인터가 저장된다.



redirection


bash는 기본적으로 stdin, stdout, stderr에 해당하는 file descriptor 3개를 가지고 있으며 이들은 각각 0,1,2에 대응


하며 모두 터미널을 가리키고 있는 상태. 이 때 bash가 command를 실행할 경우 command에 해당하는 자식 프로


세스를 fork하게 되는데, 이 때 자식 프로세스는 부모 프로세스(bash)가 가진 모든 file descriptor들을 상속받아 사


용하게 된다.



1. output redirection


command > file


> : output redirection operator


command 1> file과 같으며, 이 명령은 command로부터 발생하는 표준 출력을 file로 전송하게 된다. 구체적으로 살


펴보면, 원래 command가 사용하는 0,1,2번 file descriptor들은 모두 터미널을 가리키고 있었으나 위 명령을 실행하게


되면 command가 사용하는 1번 file descriptor가 터미널 대신 file을 가리키게 되어서 command의 표준 출력으로 나


가는 모든 output들은 터미널이 아닌 file로 향하게 된다. 일반적으로 command n> file 을 통해 command의 n번 file


descriptor가 file을 가리키도록 할 수 있다.


ex) ls > abc


ls의 표준 출력을 abc 파일로 보낸다. 구체적으로는 ls 프로그램의 1번 file descriptor가 가리키는 대상을 터미널에서


abc 파일로 변경한다.



2. input redirection


command < file


command 0< file과 같으며, 이 명령은 command의 file descriptor 0이 터미널이 아닌 file을 가리키게 한다. 따라서


command가 표준 입력을 통해 read를 수행하는 경우 command는 터미널이 아닌 file로부터 read를 수행 하게 된다.



3. file descriptor의 복사


command 2>&1


먼저 &n은 file descriptor n이 가리키는 대상에 대한 참조를 할 때 사용한다. 즉 위의 명령어를 해석해보면 comman


d를 실행하되 command의 file descriptor 2가 가리키는 대상을 file descriptor 1이 가리키는 대상과 동일하게 한


다는 의미이다(duplicating). duplicating은 aliasing과는 다른 의미인데, 위 명령어를 수행한 후 command 1> file을


수행하게 되면 command의 file descriptor 1은 file을 가리키게 되지만 file descriptor 2는 여전히 command 2>&1을


수행할 당시 file descriptor 1이 가리키던 대상을 가리키고 있게 된다.


ex) command >file 2>&1


bash가 여러개의 redirection들을 처리할 때에는 왼쪽에서 오른쪽으로 처리를 하기 때문에 여러 개의 redirection


operator들을 사용하는 경우에 redirection operator의 순서는 중요하다. 위의 명령어의 경우에는 >file 부분이 먼저 


처리되어 command의 file descriptor 1은 터미널이 아닌 file을 가리키게 된다. 그 다음 2>&1 부분이 처리되어


command의 file descriptor 2는 file descriptor 1이 가리키는 대상인 file을 가리키게 된다. 즉 위의 명령어를 사용 


하면 command가 사용하는 표준 출력 및 표준 에러가 file로 전송된다. 여러 개의 redirection들을 쓸 경우 순서(왼쪽


->오른쪽)가 중요하기 때문에 위의 명령어를 command 2>&1 >file 로 바꿔쓸 경우 의도한 결과가 나오지 않는다. 


순서를 바꿔서 명령어를 실행할 경우에는 먼저 2>&1 부분이 처리되어 command의 file descriptor 2가 file descriptor


1과 동일한 대상을 가리키게 되고, 이 상태에서 >file 부분이 처리되어 command의 file descriptor 1이 file을 가리키게


된다. 즉, file descriptor 1만이 file을 가리키게 된다.참고로 위의 명령어는 command &>file 로 줄여쓸 수 있다.



4. file descriptor closing


file descriptor가 가리키는 file을 닫기 위해서는 &- operator를 사용한다.예를 들어 stdin file descriptor를 닫을 때는


0<&-을 사용하고 stdout이나 stderr file descriptor를 닫을 때에는 각각 1>&- 와 2>&- 이렇게 사용 한다.



5. pipe


command1 | command2


위 명령은 command1의 표준 출력을 command2의 표준 입력과 연결 한다. 구체적으로는, 먼저 pipe라고 불리는 특


수한 파일 하나를 생성한다. 그리고 command1의 file descriptor 1은 이 pipe를 write 모드로 가리키게 하고,


comman2의 file descriptor 0은 이 pipe를 read 모드로 가리키게 한다. 이렇게 하면 command1이 발생시키는 표준 


출력이 터미널 대신 pipe로 가며, command2는 터미널 대신 이 pipe로부터 read를 수행한다.







Posted by huammmm1
,