ls abc와 같이 파라미터를 잘못 입력해 명령어를 입력하면, 명령어의 결과값이 아래와 같이 터미널 화면에 출력된다.
ls abc 명령어의 결과값이 터미널 화면에 출력되는 방식이 아닌, 파일에 출력되는 방식으로 작동시키기 위해 아래와 같이 명령어를 실행시켜봤다.
$ ls abc > list2.txt
# ls abc 명령어의 결과값이 파일에 잘 출력됐는 지 확인하기
$ ls
$ cat list2.txt
그런데 여전히 터미널 화면에 결과값이 출력되고 파일에 출력되지 않는다. 왜 그럴까?
리눅스에서 명령어의 실행 결과가 아닌 에러 메시지를 출력할 때는 별도의 메서드를 호출(ex. perror())해서 출력한다. 즉, 정상적인 실행 결과값을 출력하는 함수와 에러 메시지를 출력하는 함수가 구별되어 있다. 이 때, 에러 메시지를 출력하는 함수인 perror()의 역할은 표준 에러 출력이라는 곳으로 에러 메시지를 전달하는 역할을 한다. 그러면 에러 메시지를 전달 받은 표준 에러 출력은, 기본적으로 터미널 화면에 에러 메시지가 출력되도록 만든다.
** 참고) c 언어에서의 perror() 함수는 Java에서의System.err.println() 또는 Javascript에서의 console.error()와 같은 출력 함수 중 하나이다.
위 예제에서는 ls abc > list2.txt라는 명령어를 통해 표준 출력을 터미널 화면이 아닌 파일로 연결되도록 바꿨다. 하지만 표준 출력과 표준 에러 출력은 독립적인 통로로 구성되어 있기 때문에, 에러 메시지가 발생했을 때는 표준 출력이 아닌 표준 에러 출력의 통로를 거쳐 터미널 화면으로 에러 메시지가 출력된 것이다.
그럼 어떻게 해야 에러 메시지를 터미널 화면이 아닌 파일로 출력되게 만들 수 있을까?
아래 명령어와 같이 >가 아닌 2>라는 기호를 사용해야 한다. 그러면 표준 에러 출력은 파일에 저장된다. 정말 파일에 저장되는 지 확인해보자.
$ ls abc 2> list3.txt
# 표준 에러 출력이 파일에 잘 저장됐는 지 확인
$ ls
$ cat list3.txt
에러 메시지가 터미널 화면에 출력되지 않고 파일에 저장되는 걸 확인할 수 있다. 아래의 그림과 같이 작동한 것이다.
한 가지 더 테스트를 해보자.
아래와 같이 명령어를 입력했을 때 명령어의 정상적인 결과값은 어떻게 처리가 되는 지 확인해보자.
$ ls 2> list4.txt
# 표준 출력이 파일에 저장되는 지 확인
$ ls
$ cat list4.txt
에러 메시지가 아닌 정상적인 결과값은 표준 출력을 통해 전달되므로, 파일이 아닌 터미널 화면으로 출력되는 걸 확인할 수 있다.
그럼 표준 출력이랑 표준 에러 출력 둘 다 파일로 출력(= 리다이렉션)하고 싶다면 어떻게 해야 할까?
✅ ’표준 출력’과 ‘표준 에러 출력’ 둘 다 파일로 출력하려면?
서로 다른 파일로 출력하게 만들고 싶은 경우
$ ls > list.txt 2> error.txt # 정상적인 결과값을 출력하는 경우
$ ls xxx > list.txt 2> error.txt # 에러 메시지를 출력하는 경우
같은 파일로 출력하게 만들고 싶은 경우
$ ls > all.txt 2> all.txt # 이렇게 작성하면 충돌로 인해 메시지가 잘못 기록될 수 있다.
$ ls > all.txt 2>&1 # 이렇게 작성하는 것이 올바른 방식이다.
✅ 정리
표준 출력(stdout)이란, 명령어의 실행 결과를 ‘출력할 곳’으로 이동시켜주는 통로이다.
표준 출력을 어디로 연결할 지 변경할 때(= 리다이렉션)는 >를 사용한다.
표준 에러 출력(stderr)이란, 명령어 실행 시 발생한 에러 메시지를 ‘출력할 곳’으로 이동시켜주는 통로이다.
표준 에러 출력을 어디로 연결할 지 변경할 때(= 리다이렉션)는 2>를 사용한다.
👨🏻🏫
지금까지 표준 출력과 표준 에러 출력의 기본 개념에 대해 배워봤다. 다음 강의에서는 표준 출력과 표준 에러 출력의 조금 더 심화된 기능에 대해 배워보자.