리눅스 > /dev/null 2>&1의 의미? 출력 억제

리눅스 쉘 스크립트로 애플리케이션을 구동할 때 > /dev/null 2>&1라는 구문이 자주 사용됩니다. 이 짧은 구문 하나에 리눅스의 리디렉션, null 장치, 표준 스트림의 개념이 모두 담겨 있습니다. 

/dev/null이란?

리눅스에서 /dev/null은 블랙홀 같은 존재입니다. 모든 출력 값을 허공으로 날려 보냅니다. 예를 들어, 커맨드 창에 내린 명령에 대해 결과 값을 표시하지 않도록 합니다. 그래서 null 장치라고도 부릅니다. null 장치는 모든 리눅스 시스템에 존재합니다.

/dev/null이 필요한 이유

/dev/null이 필요한 이유는 기능 그대로 출력을 표시하지 않기 위함입니다. 리눅스에서 애플리케이션을 구동하면 순간순간 처리되는 정보들이 모두 출력되며 텍스트가 쏟아집니다. 사용자 입장에선 내용을 보기가 힘들고, 성가시게 느껴질 수도 있습니다. 그래서 실시간으로 출력되는 정보를 확인하는 대신 로그 파일을 따로 생성해서 그곳에 출력 정보를 기록하게끔 만드는 게 일반적입니다.

/dev/null 예시

[root@localhost ~]# echo "Hello"
Hello

우선 Hello를 출력하는 명령어를 입력했을 때 정상적으로 결과 값을 출력하는 모습입니다. 여기에 null 장치를 사용해보겠습니다. 

[root@localhost ~]# echo "Hello" 1> /dev/null
[root@localhost ~]#

표준 출력 (stdout)을 /dev/null로 리디렉션 한다는 의미입니다. 그에 따라 표준 출력인 Hello를 출력하지 않습니다. 1은 stdout을 의미하고, >는 왼쪽에 있는 걸 오른쪽에 있는 명령으로 리디렉션한다는 의미입니다.

[root@localhost ~]# echo "Hello" 2> /dev/null
Hello

이번엔 숫자 2로 쓰이는 표준에러(stderr)를 /dev/null로 리디렉션 한 구문입니다. Hello는 에러가 아니기 때문에 정상 출력됐습니다.

 

이 부분을 이해하기 위해서는 리눅스의 표준 스트림 3가지(stdin, stdout, stderr)가 무엇인지 알아야 합니다.

 

 

리눅스 stdin, stdout, stderr이란? (표준 스트림)

모든 리눅스 세 개의 표준 스트림이 존재합니다. 입력 스트림, 출력 스트림, 오류 출력 스트림입니다. 각각 stdin , stdout , stderr 라고 부릅니다. 리눅스 표준 스트림 컴퓨터에서 스트림이란 데이터

change-words.tistory.com

[root@localhost ~]# cd notExistDir
-bash: cd: notExistDir: No such file or directory
[root@localhost ~]# cd notExistDir 2> /dev/null
[root@localhost ~]#

위 예시의 연장선에서 존재하지 않는 폴더 경로로 이동하라는 명령을 내렸을 때 출력되는 stderr를 /dev/null로 리디렉션 하면 에러 메시지를 출력하지 않는 걸 확인할 수 있습니다.

> /dev/null 2>&1란?

이제 핵심입니다. > /dev/null 2>&1는 쉘 스크립트에서 굉장히 자주 사용되는 구문이기도 하고, 때에 따라 이 구문을 지울 필요가 있기도 하기에 중요합니다.

 

결론부터 말하면 > /dev/null 2>&1는 stdout과 stderr를 모두 출력하지 않겠다는 의미입니다.

[root@localhost ~]# cat --asdf > /dev/null 2>&1
[root@localhost ~]#

우선 > /dev/null는 stdout(1)을 /dev/null로 리디렉션 한다는 의미입니다. 리디렉션에 숫자가 생략되면 stdout으로 간주됩니다.

 

2>&1은 stderr(2)를 stdout(1)으로 리디렉션한다는 의미입니다. &는 구분자의 역할을 합니다. “& 뒤에 나오는 숫자는 표준 스트림을 의미한다”고 리눅스에 알려주는 용도입니다. 이게 왜 필요하냐면, 만약 1이라는 파일명이 있으면 1이라는 파일로 잘못 리디렉트 할 수 있습니다. 그래서 통상 2>1 대신 2>&1로 사용합니다.

 

정리하면 stdout은 /dev/null로 리디렉트하고, stderr는 stdout으로 리디렉트 했는데, stdout은 앞서 /dev/null로 리디렉트 했기 때문에 stdout과 stderr 모두 null 장치를 통해 출력하지 않겠다는 구문입니다.

 

가끔은 애플리케이션에 문제가 있는데 이렇다할 에러 로그도 남지 않을 때가 있습니다. 그럴 때 /dev/null를 삭제하고 애플리케이션을 재시작하면 어떤 문제가 있는지 stderr를 확인할 수 있습니다.

반응형

댓글

Designed by JB FACTORY