/dev/null

리눅스를 사용하다보면 자주 보이는 명령어 /dev/null. 사실 명령어라기 보단 쓰기용 가상 디바이스이자 가상파일이다. 그럼 쓰기용 null 장치란 말인데, 일종의 쓰레기통이라 생각하면 된다. 조금 더 자세히 알아보자.

# stdin, stderr,stdout

UNIX ecosystem에는, 텍스트를 데이터로 전송하기 위한 스트림이 존재한다.

  • stdin: 표준입력. input 데이터를 텍스트로 다룬다.
  • stdout: 표준출력. 명령어의 텍스트 결과를 저장.
  • stderr: 표준오류. 명령어가 어떤 이유에서든 오류를 만났을때 오류 메시지가 저장.

예로 아래 명령어결과는 stdout에 저장되고 텍스트를 출력한다.

echo "Hello World"
1
다음 명령어는 직전 실행된 명령의 exit status을 보여준다.
echo $?
1

명령어가 제대로 실행되면 exit status는 숫자0

잘못된 명령어를 사용하면?

jkfsjk
echo $?
1
2
오류일 경우 0이 아닌 다른 숫자가 나온다.

# file descriptor

UNIX ecnosystem은 각 파일에 숫자를 할당한다. 특히 stdout과 stderr는 1과 2로 정의돼있다.(stdin은 0) 그리고 stdout과 stderr은 다른 파일로 전송 가능하다. 아래는 stdout을 파일로 전달하는 예이다.

echo "Hello World" 1> hello.txt
혹은
echo "Hello World" > hello.txt # "1>"에서 "1"은 생략 가능
1
2
3
echo출력이 hello.txt에 쓰여졌다

이번에는 stderr을 텍스트 파일로 전달해 보자

sfkjskle 2> error.txt
1
오류출력이 error.txt에 쓰여졌다

echo명령 결과 중 성공한 출력결과(1> 부분)가 hello.txt로 전달됐고, 명령어 sfkjskle의 결과 중 오류출력(2> 부분)이 error.txt로 전달됐다.

# /dev/null로 출력값 전달

아래 명령어를 실행해보자. /sys폴더에 있는 hello라는 string 값을 찾는 명령어다.

grep -r hello /sys/
1

권한이 없어서 파일에 접근 할 수 가 없다는 오류가 출력된다. 오류출력이 보기 싫다면? 오류 출력을 /dev/null로 보내버리자.

grep -r hello /sys/ 2> /dev/null
1

오류출력이 보이지 않는다.

반대의 경우도 살펴보자. 아래는 구글에 ping을 보내는 명령어다.
ping google.com
1

만약 성공한 출력은 무시하고, 실패한 오류출력만 보고 싶다면?
ping google.com 1> /dev/null # 성공결과 출력(1> 부분)은 /dev/null로 보냄
1

오류출력만 보인다.

# 모든 output을 /dev/null로

출력결과가 필요 없을때, 모든 출력 데이터를 /dev/null로 보내는 명령어는 다음과 같다.

grep -r hello /sys/ 1> /dev/null 2>&1
1

두부분으로 되어있다.

  1. grep -r hello /sys/ 1> /dev/null
  • grep -r hello /sys/의 표준출력을 /dev/null로 전달.
  1. 2>&1
  • 오류출력을 표준 출력으로 보내라. 표준출력을 기록하지 않고 있으므로, 오류 출력도 기록하지 않게 된다.

(참고) 명령어1&명령어2:  명령어1을 백그라운드로 실행하고 명령어2를 실행

# 정리

  • 프로세스 성공 return값(exit status)은 0, 실패는 0이 아닌 int값
  • 0은 stdout으로, 0이외 값은 stderr로 보내진다.
  • stout의 file descriptor 값은 1, stderr는 2
  • /dev/null은 스트림 쓰레기통