-
표준 오류(stderr) 와 표준 출력(stdout) 을 하나의 스트림으로 합치기 위해 사용하는 리디렉션 구문임
- 숫자 1은 stdout, 2는 stderr를 의미하며, &는 파일 디스크립터를 참조한다는 표시로 사용됨
-
2>&1은 “stderr를 현재 stdout이 향하는 곳으로 보낸다”는 뜻이며, 출력 순서에 따라 결과가 달라짐
- 예를 들어 command >file 2>&1은 두 스트림 모두 파일로 보내지만, command 2>&1 >file은 stderr만 콘솔에 남음
- Bash 및 POSIX 셸에서 출력 병합, 로그 저장, 파이프 처리 시 자주 쓰이는 핵심 리디렉션 문법임
파일 디스크립터와 기본 개념
-
0, 1, 2는 각각 stdin, stdout, stderr를 의미
-
/usr/include/unistd.h에 정의되어 있음
-
#define STDIN_FILENO 0, #define STDOUT_FILENO 1, #define STDERR_FILENO 2
-
>는 출력 리디렉션, <는 입력 리디렉션을 의미
-
>는 파일을 새로 쓰기, >>는 파일에 추가하기
-
& 기호는 파일 이름이 아닌 디스크립터를 참조함을 나타냄
- 따라서 2>1은 파일 이름이 “1”인 파일로 리디렉션하지만, 2>&1은 stderr를 stdout으로 복제함
2>&1의 동작 원리
-
2>는 stderr를 리디렉션하라는 의미, &1은 stdout의 파일 디스크립터를 참조
- 결과적으로 stderr가 stdout과 동일한 목적지로 향함
- 예시:
-
ls -ld /tmp /tnt >/dev/null 2>&1 → 두 출력 모두 /dev/null로 버림
-
ls -ld /tmp /tnt 2>&1 >/dev/null → stderr만 콘솔에 남음
-
리디렉션은 왼쪽에서 오른쪽으로 처리되므로, 순서가 다르면 결과도 달라짐
리디렉션 순서의 중요성
-
command >file 2>&1
- stdout을 먼저 파일로 보낸 뒤, stderr를 stdout으로 복제 → 두 스트림 모두 파일로 감
-
command 2>&1 >file
- stderr를 현재 stdout(콘솔)에 복제한 뒤, stdout만 파일로 보냄 → stderr는 여전히 콘솔에 출력
- Bash는 리디렉션을 순서대로 처리하므로, 명령어 작성 시 순서 주의 필요
다양한 리디렉션 예시
-
echo test >file.txt → stdout을 파일로
-
echo test 2>file.txt → stderr를 파일로
-
echo test 1>&2 → stdout을 stderr로
-
command &>file 또는 command >&file → stdout과 stderr 모두 파일로 (Bash 단축형)
-
command 2>&1 | tee -a file.txt → 두 스트림을 파일과 터미널에 동시에 출력
고급 사용법과 Bash 4.0 이후 기능
- Bash 4.0부터 프로세스 서브스티튜션을 이용한 분리 출력 가능
-
ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /')
- stdout과 stderr를 각각 다른 필터로 전달
-
|&는 2>&1 |의 축약형으로, 두 스트림을 합쳐 파이프로 전달
-
set -o noclobber 옵션은 기존 파일 덮어쓰기를 방지하며, >|로 예외 처리 가능
실무 활용 예시
-
g++ main.cpp 2>&1 | head → 컴파일 오류를 포함한 초기 출력만 확인
-
perl test.pl > debug.log 2>&1 → 모든 출력과 오류를 로그 파일에 저장
-
foo 2>&1 | grep ERROR → stdout과 stderr 모두에서 “ERROR” 문자열 검색
-
docker logs container 2>&1 | grep "some log" → 로그 전체를 파이프로 전달
핵심 요약
-
2>&1은 stderr를 stdout으로 복제하는 POSIX 표준 구문
-
리디렉션 순서가 결과를 결정하므로, 명령 작성 시 주의 필요
- Bash에서는 &>로 두 스트림을 동시에 처리할 수 있으며,
로그 관리·파이프 처리·에러 병합 등 다양한 자동화 스크립트에서 필수적으로 사용됨