기술적인 관점에서 /dev/null은 가상 디바이스 파일(virtual device file)입니다. 프로그램 입장에서는 이 파일을 일반 파일과 똑같이 취급합니다. 유틸리티가 이런 소스에 데이터를 요청하면 운영체제가 데이터를 제공하는데, 디스크에서 읽어오는 대신 데이터를 동적으로 생성합니다. 대표적인 예로 /dev/zero가 있습니다.
하지만 /dev/null의 경우에는 파일에 '쓰기'를 하는 용도로 사용됩니다. /dev/null에 쓴 모든 데이터는 버려지고, 잊혀지고, 허공으로 사라집니다. 이것이 왜 유용한지 이해하려면 먼저 리눅스나 *nix 계열 운영체제에서 표준 출력(standard output)과 표준 에러(standard error)가 어떻게 동작하는지 기본적인 개념을 알아야 합니다.
stdout과 stderr의 이해
커맨드라인 유틸리티는 두 가지 유형의 출력을 생성할 수 있습니다. 일반적인 결과는 stdout(표준 출력)으로 전송되고, 오류 메시지는 stderr(표준 에러)로 전송됩니다.
기본적으로 stdout과 stderr는 터미널 창(또는 콘솔)에 연결되어 있습니다. 즉, stdout과 stderr로 전송된 내용은 화면에 그대로 표시됩니다. 하지만 셸 리다이렉션(shell redirection)을 사용하면 이 동작을 바꿀 수 있습니다. 예를 들어 stdout을 파일로 리다이렉트하면 출력이 화면에 표시되는 대신 파일에 저장되어 나중에 읽을 수 있습니다. 또는 stdout을 LED나 LCD 디스플레이 같은 물리적 장치로 보낼 수도 있습니다.
파이프와 리다이렉션에 대해 더 자세히 알고 싶다면 별도의 심화 글을 참고하는 것도 좋습니다. 핵심 문법만 정리하면 다음과 같습니다.
2>: 표준 에러(stderr)를 리다이렉트합니다. 예:2>/dev/null,2>/home/user/error.log1>: 표준 출력(stdout)을 리다이렉트합니다.&>: 표준 에러와 표준 출력을 모두 리다이렉트합니다.
/dev/null로 불필요한 출력 없애기
출력에는 표준 출력과 표준 에러 두 종류가 있으므로, 첫 번째 활용 사례는 이 중 한쪽을 걸러내는 것입니다. 실제 예제를 통해 살펴보는 것이 이해하기 쉽습니다. 전원 설정과 관련된 파일을 찾기 위해 /sys 디렉터리에서 특정 문자열을 검색한다고 가정해 보겠습니다.
grep -r power /sys/
일반 사용자(루트가 아닌 계정)가 읽을 수 없는 파일이 많기 때문에 "Permission denied" 오류가 수없이 발생합니다.
이런 오류 메시지는 출력을 어지럽혀 원하는 결과를 찾기 어렵게 만듭니다. "Permission denied" 오류는 stderr에 해당하므로, 이를 /dev/null로 리다이렉트하면 깔끔하게 제거할 수 있습니다.
grep -r power /sys/ 2>/dev/null
보시다시피 훨씬 읽기 편해졌습니다.
반대로, 표준 출력을 걸러내고 오류만 확인하고 싶은 경우도 있습니다.
ping google.com 1>/dev/null
위 스크린샷을 보면, 리다이렉션 없이 실행한 ping은 목적지에 도달했을 때 평소와 같은 출력을 표시합니다. 반면 두 번째 명령은 네트워크가 정상인 동안에는 아무것도 표시하지 않다가, 연결이 끊기는 순간 오류 메시지만 화면에 나타납니다.
stdout과 stderr를 서로 다른 위치로 각각 리다이렉트할 수도 있습니다.
ping google.com 1>/dev/null 2>error.log
이 경우 stdout 메시지는 전혀 표시되지 않고, 오류 메시지만 error.log 파일에 저장됩니다.
모든 출력을 /dev/null로 보내기
때로는 모든 출력을 없애는 것이 유용할 수 있습니다. 방법은 두 가지입니다.
grep -r power /sys/ >/dev/null 2>&1
>/dev/null은 "stdout을 /dev/null로 보내라"는 의미이고, 두 번째 부분인 2>&1은 "stderr를 stdout으로 보내라"는 의미입니다. 여기서 stdout을 지칭할 때 단순히 1이 아니라 &1로 표기해야 합니다. 2>1이라고 쓰면 stderr가 "1"이라는 이름의 파일로 리다이렉트되어 버립니다.
여기서 중요한 점은 순서가 중요하다는 것입니다. 리다이렉트 매개변수의 순서를 다음과 같이 바꾸면:
grep -r power /sys/ 2>&1 >/dev/null
의도한 대로 동작하지 않습니다. 그 이유는 2>&1이 해석되는 순간 stderr가 stdout으로 전송되어 화면에 표시되고, 그다음에 stdout이 /dev/null로 보내져 억제되기 때문입니다. 최종 결과적으로 모든 출력이 억제되는 것이 아니라 오류 메시지만 화면에 남게 됩니다. 올바른 순서가 기억나지 않는다면, 훨씬 입력하기 쉬운 간단한 리다이렉션이 있습니다.
grep -r power /sys/ &>/dev/null
이 경우 &>/dev/null은 "stdout과 stderr를 모두 이 위치로 리다이렉트하라"는 의미와 같습니다.
/dev/null 리다이렉션이 유용한 다른 예제들
디스크가 순차 데이터를 얼마나 빠르게 읽을 수 있는지 확인하고 싶다고 가정해 봅시다. 이 테스트는 아주 정밀하지는 않지만 충분히 실용적입니다. dd 명령을 사용할 수 있는데, dd는 stdout으로 출력하거나 파일에 쓰도록 지정할 수 있습니다. of=/dev/null 옵션을 사용하면 이 가상 파일에 쓰도록 지시할 수 있으며, 셸 리다이렉션조차 필요하지 않습니다. if=는 읽어올 입력 파일의 위치를, of=는 쓸 출력 파일의 이름을 지정합니다.
dd if=debian-disk.qcow2 of=/dev/null status=progress bs=1M iflag=direct
또 어떤 상황에서는 서버에서 얼마나 빠르게 다운로드할 수 있는지 확인하고 싶지만, 디스크에 불필요하게 데이터를 쓰고 싶지 않을 수 있습니다. 간단합니다. 일반 파일에 쓰는 대신 /dev/null에 쓰면 됩니다.
wget -O /dev/null https://ftp.halifax.rwth-aachen.de/ubuntu-releases/18.04/ubuntu-18.04.2-desktop-amd64.iso
마무리
이 글의 예제들이 /dev/null을 자신만의 창의적인 방식으로 활용하는 데 영감을 주었기를 바랍니다.
이 특별한 디바이스 파일의 흥미로운 활용 사례를 알고 계신가요? 아래 댓글로 지식을 나눠주세요!