linux에서 Input/Output(I/O) redirection은 command를 실행할 때 standard input와 standart output을 바꿀 수 있도록 해주는 기능이다.
standard input은 표준 입력을 의미하고 우리가 키보드로 입력하는 것이 표준 입력으로 들어간다.
standard output은 표준 출력을 의미하고 우리가 모니터 화면으로 보는 것이 표준 출력이라고 할 수 있다.
표준 입출력 또한 파일 형태로 관리가 되기 때문에 file descriptor가 할당되어 있다.
표준 입력 (STDIN) : 0
표준 출력 (STDOUT) : 1
표준 에러 (STDERR) : 2
이미 내부적으로 0, 1, 2 는 위와 같이 표준 입출력, 에러에 할당되어 있으므로 우리가 첫 파일을 open해도 파일 디스크립터는 대부분 3부터 할당된다.
출력 스트림의 도착을 파일로 설정
> file 라고 작성하면 입력 스트림은 stdin, 출력 stream은 'file'이라는 파일이기 때문에 입력을 기다린다. user가 입력을 모두 해주고 eof로 표준 입력을 종료하면 file이라는 파일에 해당 내용이 들어가 있음을 확인할 수 있다.
ls 명령어는 위와 같이 해당 디렉토리의 파일들을 list up 하여 출력하는데, 다음과 같이 표준 출력을 ls_outfile이라는 파일로 연결해주면 모니터 상으로는 ls의 결과를 확인할 수 없고 ls_outfile에 출력 내용이 저장되어 있다.
입력 스트림을 파일로 설정
keyboard(stdin)을 통해 입력을 받는 것이 아니라 file에서 입력을 받도록 한다.
< file 이라고 하면 file 내용이 입력 버퍼에 들어가 있는 상태가 된다. 위의 캡쳐 사진은 zsh에서 이를 실행했기 때문의 zsh의 기능으로 입력 버퍼 내용이 보이는 것이다. zsh 기능으로 고생하기 쉽상이니 과제를 할 때는 항상 bash에서 test 해보는 것을 권한다 !
bash 실행 방법
bash로 했을 때는 출력하지 않고 입력 버퍼에 남아있는 문자들은 모니터에 보이지 않는 것을 확인할 수 있다. exit으로 bash 종료 !
cat 명령어는 기본적으로 표준 입력을 기다리고 입력이 들어오면 해당 내용을 출력해주는데, stdin을 다른 파일로 연결해주면 파일 내용을 입력으로 받게 된다.
pipex에서의 heredoc !
정식 명칭은 here document 이다.
tag가 입력으로 들어올 때까지 입력을 넣어주면 그 때까지 넣어준 입력이 입력 스트림으로 들어간다. 위와 같이 넣어주는 것은 실제로 heredoc_out에 출력되지는 않는다. 그 이유는 << END를 통해 입력 스트림에 들어오긴 했지만 출력을 하는 동작은 전혀 없기 때문이다. 만약 cat과 같이 출력해주는 명령어를 사용하면 cat이 입력 버퍼의 내용을 출력하므로 heredoc_out에 해당 내용이 적절히 들어가는 것을 확인할 수 있다.
END와 같이 tag가 아니라 eof로 종료해도 eof 이전까지의 내용은 입력 스트림에 다 들어가서 동일하게 처리된다.
그리고 tag의 경우에는 정확히 tag와 동일하게 들어올 때만 인식한다.
here document를 사용하여 heredoc_out을 다음과 같이 만들어두었다.
이 때 << END cat >> heredoc_out을 하면 어떻게 될까?
우선 << END가 있으므로 입력 스트림에 입력을 넣어줘야 할 것이다. 이렇게 입력을 넣었을 때 heredoc_out은 어떻게 변했을까? 확인해보면 위와 같이 입력으로 넣어준 extra content가 기존 heredoc_out에 추가된 것을 볼 수 있다.
> file 은 파일에 덮어쓴 반면, >> file은 파일에 추가(append) 작업을 해준다.
윗 부분까지가 pipex 상에서 필요한 redirection이고, 아래 기술한 redirection은 추가적인 공부를 위한 정리이니 참고 바란다.
minishell에서도 아래와 같이 fd를 redirection 하는 부분은 구현하지 않았다.
fd를 redirection 하는 부분을 구현하려면 parsing 부분이 다소 까다로워진다 .. 🌟
위에서 살펴본 > file은 사실 1 > file 이다.
표준 출력을 file로 redirection으로 우회하고 싶을 때 사용하는 것이었다.
이 때, 어떤 command 작업에서 stdin, stdout 등이 아닌 파일에 대해서 우회시키고 싶을 수 있다.
직접 open한 함수에 대해서는 직접 거의 사용해본 적이 없어 따로 정리하지는 않겠다.
다만 2(STDERR, 표준 에러)의 경우 가끔씩 사용하기도 하니 표준 에러를 예시로 들어 정리를 하려고 한다.
표준 에러는 에러 문구 등을 출력할 때 주로 사용하는 스트림인데, 어떤 프로그램 상에서 에러를 표준 에러로 뱉을 때 이를 파일에 로그 형식으로 저장하고 싶은 경우
program 2>error_log
와 같이 작성하면 표준 에러 스트림이 error_log 파일로 redirection 되었기 때문에 2로 출력될 문구들이 error_log에 기록된다.
test.c를 위와 같이 작성하고 테스트 해보면 다음과 같은 결과를 얻을 수 있다.
리다이렉션 왼쪽에 fd를 쓰는 경우 반드시 기호와 붙여서 써야 한다. 그렇지 않으면 fd 번호가 아닌 "2"라는 파일명 으로 인식한다.
이는 위에서 설명한 (fd)>file 에서 마찬가지로 append 작업으로만 변경된 리다이렉션이라고 생각하면 된다 !
>&, <& 은 리다이렉션의 오른 편에 fd 번호를 써주기 위해 사용하는 기호이다. &를 붙여주지 않으면 fd 번호가 아닌 파일명으로 인식한다.
리다이렉션은 영향 범위가 pipe 단위로 나뉜다고 생각해야 한다.
pipex에서 요구하는 대로
< infile cmd1 | cmd2 > outfile
이라고 하면 이 command-line의 전체의 stdin, stdout이 infile과 outfile로 setting 되는 것이 아니다.
pipe 단위로 자식 process를 띄울텐데 process 별로 stdin, stdout 스트림이 별개로 있기 때문에 파이프 단위로 나뉜다고 볼 수 있다.
이 부분에 대한 개념은 추후 minishell 과제를 할 때 이해가 필요하다.
🦋 pipex repo address
https://github.com/kyj93790/42-cursus/tree/master/pipex
참고 자료
https://www.educative.io/answers/how-to-do-input-output-redirection-in-linux
https://woorld52.tistory.com/11