redirection - 표준입출력 방향 재지정

우리가 사용하는 많은 명령어, 프로그램들은 일종의 출력을 만들어내서 터미널에 띄어준다.

이러한 출력은 두가지 형식을 포함하는데 첫번째가 바로 프로그램의 결과값으로, 해당 프로그램이 어떤 메시지를 출력하라고 설계해놓은 데이터인 것이다.

두번째는 프로그램이 어떻게 돌아가고 있는지를 말해주는 상태 혹은 오류 등과 같은 메시지 형식이다.

“모든 것은 파일이다” 라는 유닉스 정신을 바탕으로 보면, 프로그램은 stdout / stderr 등의 특수한 파일에 메시지를 보낸다.

ls 와 같은 프로그램은 사실 표준출력(stdout)에 명령어에 대한 결과를 보내고, 표준오류(stderr)에 상태 메시지를 저장한다.

이는 콘솔과 기본적으로 연결되어 있으며, 디스크에는 따로 저장되지는 않는다.

표준입력(stdin)과 같은 경우 역시 기본적으로 키보드에 직접 연결되어 사용자들이 입력하는 내용을 가져오는데, 이 때 리다이렉션을 통해 출력과 입력의 방향을 조절해 줄 수 있다.

일반적으로 사용자 입력으로부터 stdin 을 가져오고 화면에 stdout 으로 출력하지만, 이 내용들을 다른 곳으로 연결시키는 것이다.


표준 출력 재지정

화면에 출력하는 대신, 다른 파일에 출력되도록 지정하기 위해서 파일명 앞에 > 연산자를 사용한다.

마치 화살표와 비슷한 느낌으로 이해하면 편하다.

ls . > output.txt 와 같이 사용하는데, 현재 디렉토리의 ls 내용들을, output.txt 라는 파일에 저장한다는 것이다.

리다이렉션을 통해 출력 방향을 지정할 때, 목적 파일은 항상 처음부터 다시 작성된다.

따라서 ls not_exist_filename > output.txt 처럼 프로그램이 결과를 내지 못할 경우, 파일이 새로 초기화됐다가 다시 쓰려는 중에 잘림 현상이 발생한 것이다.

만약 기존 파일 내용을 지우지 않고 덧붙여서 출력하고 싶을 경우, » 를 사용해주면 된다.

ls . >> output.txt 와 같이 사용하면, 기존 내용 아래에 새롭게 붙여서 생성해줄 수 있다.


표준 오류 재지정

위에서 ls not_exist_filename > output.txt 처럼 했을 경우, 터미널 창에는 오류 메시지가 나타날 것이다.

ls 의 결과는 우리가 output.txt 로 재지정 했지만, 상태 메시지 등과 같은 stderr 에 대해서는 따로 지정해주지 않았기 때문이다.

파일 디스크립터를 참조하여 해당 번호로 지정된 파일 스트림 중 어디에라도 출력을 할 수 있다.

표준 입력은 0번, 출력은 1번, 오류는 2번의 파일 디스크립터로 표현한다.

ls not_exist_filename 2> error.txt와 같이 파일 디스크립터 2번이 리다이렉션 연산자 앞에 위치하며 error.txt 파일에다가 표준오류에 대한 내용들을 저장한다.

표준 출력과 표준 오류를 하나의 파일에 같이 저장하고 싶은 경우엔, 리다이렉션을 여러번 지정해준다.

ls dir > result.txt 2>&1
ls dir &> result.txt

첫번째 명령어는 일반적인 방법으로, 두번의 리다이렉션을 통해 표준출력과 표준오류를 지정해주는데, 표준 오류의 재지정은 표준 출력의 재지정 이후에 이루어져야만 한다.

두번째 명령어는 bash 의 최신 버전에서, 좀 더 간소화시킨 방법이다.


표준 입력 재지정

표준 입력을 사용하는 명령어로는 cat 이 있다.

일반적으로 cat 명령어는 하나 이상의 파일을 읽어서, 표준 출력으로 보여주는 명령어다.

cat file1 file2 ... 등과 같이 사용하여, 하나의 파일 뿐만 아니라 여러 파일을 하나로 합쳐서 출력해주기도 한다.

이를 표준 입력으로 사용하기 위해서는, 파일을 넘겨주지 않고 cat만 치면 된다.

아무런 인자 없이 사용하면 표준 입력으로부터 데이터를 읽기 때문에, 입력을 기다리는 상태로 되며, 사용자가 ctrl + D 를 누를 때 까지 키보드로부터 받은 표준 입력을 출력으로 내보낸다.

따라서 cat > output.txt는, cat 을 통해 읽어들인 표준 입력의 내용들을 output.txt 로 리다이렉션하는 것이다.

cat < output.txt    # 표준 입력으로 재지정
cat output.txt      # 결과는 같다

위처럼 연산자를 입력하는 것과 파일명을 입력하는 것은 크게 차이가 없지만, 표준 입력을 파일로 재지정했다는 사실을 명세한다는 점에서 다르다.

이런 리다이렉션들은 파이프라인과 연계되었을 때 강력하고 유용하므로 많이 사용해서 익숙해지도록 하자.