# "2>&1"은 무엇을 의미하나?

> Clean Markdown view of GeekNews topic #27061. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=27061](https://news.hada.io/topic?id=27061)
- GeekNews Markdown: [https://news.hada.io/topic/27061.md](https://news.hada.io/topic/27061.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2026-02-28T03:38:22+09:00
- Updated: 2026-02-28T03:38:22+09:00
- Original source: [stackoverflow.com](https://stackoverflow.com/questions/818255/what-does-21-mean)
- Points: 25
- Comments: 1

## Summary

**`2>&1`**은 셸에서 **표준 오류(stderr)**를 **표준 출력(stdout)**과 같은 목적지로 보내는 리디렉션 구문입니다. 숫자 1과 2는 각각 stdout과 stderr의 파일 디스크립터를 의미하며, `&`는 파일이 아닌 디스크립터 참조를 나타냅니다. 리디렉션은 **왼쪽에서 오른쪽 순서로 처리**되기 때문에 `command >file 2>&1`과 `command 2>&1 >file`의 결과가 달라집니다. 로그 병합, 파이프 처리, 자동화 스크립트 작성 시 출력 흐름을 제어하는 핵심 문법으로 자주 활용됩니다.

## Topic Body

- **표준 오류(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에서는 `&>`로 두 스트림을 동시에 처리할 수 있으며,  
  **로그 관리·파이프 처리·에러 병합** 등 다양한 자동화 스크립트에서 필수적으로 사용됨

## Comments



### Comment 52060

- Author: neo
- Created: 2026-02-28T03:38:22+09:00
- Points: 1

###### [Hacker News 의견들](https://news.ycombinator.com/item?id=47171233) 
- Unix의 **syscall API** 관점에서 보면 `2>&1`은 `dup2(1, 2)`와 동일한 의미임  
  고전적인 Unix 셸에서는 이게 전부지만, 현대 셸에서는 상태를 추적하기 위한 내부 bookkeeping이 추가됨  
  redirection은 **왼쪽에서 오른쪽으로** 순차적으로 실행되며, pipe 연산자는 fork와 dup의 조합으로 동작함  
  다만 `dup2(2, 1)`을 `2<1`처럼 이해하면 직관적이지만, I/O 의미상으로는 잘못된 해석임
  - iPhone Safari에서 “dup2(2, 1)”을 검색했더니 이 스레드가 두 번째로 나왔음  
    [man7 dup2 문서](https://man7.org/linux/man-pages/man2/dup.2.html)와 [Arch Linux dup2 문서](https://man.archlinux.org/man/dup2.2.en) 사이에 있었음  
    봇들이 이걸 읽고 있다는 게 놀라움
  - 이런 이유 때문에 많은 사람들이 **POSIX 셸 언어**를 불편하게 느끼는 것 같음  
    너무 많은 문법적 설탕이 내부 메커니즘을 가려버림  
    Lisp처럼 단순한 구조를 매크로로 확장하는 언어와 달리, 셸은 문법 규칙이 복잡하고 직관성이 떨어짐  
    결국 프로그래머와 시스템 관리자의 **자존심 충돌**이 이런 불만을 낳는 것 같음
  - 이 방식의 재미있는 응용은 초기화되지 않은 파일 디스크립터를 설정하는 것임  
    ```bash
    >&1 echo "stdout"
    >&2 echo "stderr"
    >&3 echo "fd 3"
    ./foo.sh 3>&1 1>/dev/null 2>/dev/null
    ```  
    이렇게 하면 **특정 출력만 남기고 나머지를 무음 처리**할 수 있음  
    단, 미리 열지 않으면 “Bad file descriptor” 오류가 남
  - 셸이 프로그램을 실행할 때는 항상 fork를 수행함  
    redirection은 exec 전에 dup을 사용하고, pipe는 두 번의 fork와 `pipe` syscall을 사용함  
    **BASH 매뉴얼**이 정말 잘 되어 있으니 [공식 문서](https://www.gnu.org/software/bash/manual/bash.html#Redirections)를 참고하는 게 좋음
  - Unix API, C, 셸, Perl 사이에는 강한 **일관성**이 있음  
    하지만 현대 언어나 Unix 외부의 언어에서는 그 감각이 사라짐

- 결국 **공식 문서(RTFM)** 를 직접 읽는 게 가장 확실함  
  [Bash Redirections 매뉴얼](https://www.gnu.org/software/bash/manual/html_node/Redirections.html)
  - 물론 어디를 찾아야 하는지 아는 사람은 드묾  
    대부분은 구글링으로 답을 찾고, 그런 질문이 쌓여야 검색 결과가 생김  
    Stack Overflow의 다양한 관점이 초보자에게는 더 도움이 됨
  - 그런데 요즘은 **구글 검색이 쓸모없음**  
    일반 사용자는 원하는 정보를 찾기 어려움

- Stack Overflow의 답변이 내 생각을 그대로 표현해서 그대로 인용함  
  `&2>&1`이 아니라 `2>&1`인 이유는 `&`가 redirection 문맥에서만 파일 디스크립터를 의미하기 때문임  
  PowerShell도 같은 문법을 유지한 게 흥미로움
  - PowerShell에는 **7개의 스트림**이 있음: Success, Error, Warning, Verbose, Debug, Information, Progress  
    [공식 문서 링크](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_output_streams?view=powershell-7.5)
  - 다만 PowerShell은 문법을 빌렸지만 **의미론을 망침**  
    `2>&1 > file` 순서가 Unix와 반대라 의도한 결과가 나오지 않음  
    7.4 이전 버전에서는 **바이트 스트림 손상** 문제도 있었음  
    [관련 문서](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_redirection?view=powershell-7.5)
  - `>` 앞의 숫자는 어떤 파일 디스크립터를 리디렉션할지 지정함  
    `>foo`는 `1>foo`와 같음  
    `2>>&1`처럼 쓰면 파일 이름 `1`이 생기므로 의미가 없음
  - 사실 혼란스러울 이유가 없음  
    `>`는 stdout, `2>`는 stderr, `&1`은 stdout을 의미함
  - `file1>file2`도 대칭적이지 않음  
    `/dev/stderr>/dev/stdout`이 더 직접적인 대응임

- Claude의 설명이 가장 이해하기 쉬웠음  
  `2>&1`은 “에러 출력을 일반 출력과 같은 곳으로 보내라”는 뜻임  
  - `2`는 에러 출력, `>`는 “보내기”, `&1`은 “현재 stdout이 향하는 곳”을 의미함
  - 좀 더 정확히 말하면 `2`는 **파일 디스크립터 2**, `> `는 **할당**, `&1`은 **파일 디스크립터 1**을 의미함
  - 하지만 이런 설명은 이미 Stack Overflow의 두 번째 답변(dbr의 답변)과 거의 동일함  
    LLM으로 얻는 것보다 직접 링크를 클릭하는 게 더 효율적임

- 사람에게 질문하던 **Stack Overflow 시절이 그립다**는 생각이 듦  
  하지만 이제는 다시 그 시대로 돌아가기 어려움
  - 2025년 이후로 “좋았던 옛날”에 대한 향수가 갑자기 커졌음  
    하지만 그 시절에도 **게이트키핑과 냉소적인 분위기**가 많았음  
    인간 중심의 협업이 항상 낭만적이진 않았음
  - 예전엔 **AI의 군더더기 없는 답변**이 좋았음  
    불필요한 서론 없이 바로 핵심만 전달했음
  - 질문하기 전에 검색부터 하는 게 기본 예절이었음 :)
  - “인간에게 묻는 게 더 낫다”는 말에는 동의하지 않음  
    인간에게는 눈치, 평가, 경쟁심 같은 **사회적 부담**이 따름  
    LLM은 그런 부담 없이 **중립적이고 예의 바른 응답**을 줌

- 셸의 동작은 **문맥 의존적**이라 &의 의미가 위치마다 달라짐  
  `IFS=\| read A B C <<< "first|second|third"`처럼 한 줄 안에서만 지역적으로 적용됨  
  줄 끝의 &는 백그라운드 실행, 중간의 &는 redirection 의미로 다름  
  이런 패턴은 익히기 어렵지만, 결국 배워야 하는 부분임

- 우리가 쓰는 시스템이 얼마나 **고대적**인지 새삼 느껴짐  
  파일 디스크립터를 숫자로 다루는 건 포인터를 사용자에게 직접 주는 것과 같음  
  이름 기반 접근이 가능했으면 좋겠음  
  - 하지만 당시에는 **사용자가 곧 프로그래머**였음  
  - 목적지에는 이름을 쓸 수 있음. `&`는 그게 파일이 아니라 디스크립터임을 알려주는 역할임  
    `<`는 이미 입력 리디렉션으로 쓰이고 있어서 대체 불가였음  
  - 이런 단순하고 논리적인 도구들이 **수십 년간 유지된다는 점**이 교훈적임  
  - `2>/dev/stdout`처럼 쓰면 `2>&1`과 비슷하지만 완전히 같지는 않음  
    `/dev/stdout`은 좀 더 **친숙한 이름 기반 접근**임  
  - 나는 오히려 이런 **고풍스러운 셸의 단순함**이 좋음  
    15년 전 스크립트가 지금도 그대로 동작함

- 리디렉션은 정말 흥미로운 기능임  
  예를 들어 `diff <(seq 1 20) <(seq 1 10)`처럼 **프로세스 치환**을 자주 씀  
  - 하지만 Unix 도구들이 파일 디스크립터를 더 잘 지원하지 못하는 게 아쉬움  
    파일, 스트림, 소켓을 직접 프로세스에 전달할 수 있다면 훨씬 강력할 것임  
    Bash에서 소켓을 직접 열어 다른 프로그램에 넘길 수 있다면 **sandboxing**도 쉬워질 것임  
    [^1]: `/dev/tcp`는 있지만 기능이 제한적임  
  - 다만 “파일 리디렉션”이라는 표현은 약간 오해의 소지가 있음  
    실제로는 **named pipe**로 구현되어 있어서 seek이 불가능함  
    그래서 Zsh에는 임시 파일을 쓰는 `=(command)` 구문이 추가됨

- 나는 `2>&1`을 “2가 1의 **주소로 들어간다**”라고 외워서 이해했음

- ‘2>&1’과 리디렉션을 깊이 다룬 글로는  
  [Understanding Linux's File Descriptors: A Deep Dive Into '2>&1' and Redirection](https://news.ycombinator.com/item?id=41384919)  
  [관련 토론 링크](https://news.ycombinator.com/item?id=39095755)
  - 나는 면접 때마다 **O’Reilly의 Essential System Administration**을 참고함  
    [책 링크](https://www.oreilly.com/library/view/essential-system-administration/0596003439/)
