표준 입출력과 리다이렉션
모든 리눅스 명령어는 세 개의 통로를 가지고 있습니다. 데이터가 들어오는 입구, 결과가 나가는 출구, 그리고 오류가 나가는 비상구입니다. 이 세 통로를 자유롭게 연결하고 끊는 기술이 리다이렉션입니다.
stdin, stdout, stderr
세 가지 표준 스트림을 파일 디스크립터 번호로 구분합니다.
| 스트림 | 번호 | 기본 연결 | 설명 |
|---|---|---|---|
| stdin | 0 | 키보드 | 명령어에 데이터를 입력하는 통로 |
| stdout | 1 | 터미널 화면 | 정상 출력 결과가 나오는 통로 |
| stderr | 2 | 터미널 화면 | 오류 메시지가 나오는 통로 |
기본 상태에서는 입력은 키보드에서 오고, 출력과 오류는 터미널 화면으로 나갑니다. 리다이렉션은 이 기본 연결을 파일이나 다른 스트림으로 바꾸는 것입니다.
출력 리다이렉션
> 기호로 출력을 파일로 보냅니다.
# stdout을 파일로 저장 (파일이 있으면 덮어씀)ls -la > file_list.txtcat file_list.txt
total 48
drwxr-xr-x 6 ubuntu ubuntu 4096 Apr 24 09:00 .
drwxr-xr-x 3 root root 4096 Apr 20 10:00 ..
-rw-r--r-- 1 ubuntu ubuntu 220 Apr 20 10:00 .bash_logout
# 파일에 추가 (덮어쓰지 않고 이어붙임)echo "=== 추가 목록 ===" >> file_list.txtls ~/scripts >> file_list.txt
# stderr만 파일로 저장find / -name "*.conf" 2> errors.txt# stderr를 화면에 보여주지 않으려면find / -name "*.conf" 2> /dev/null
# stdout과 stderr 모두 파일로 저장find / -name "*.conf" > results.txt 2>&1# 위와 동일한 최신 문법 (Bash 4+)find / -name "*.conf" &> results.txt
2>&1은 "stderr(2)를 stdout(1)이 가는 곳으로 보내라"는 뜻입니다. 순서가 중요합니다. > results.txt 2>&1처럼 stdout 리다이렉션 뒤에 와야 합니다.
리다이렉션 기호를 정리하면 다음과 같습니다.
| 기호 | 의미 |
|---|---|
> |
stdout을 파일로 (덮어씀) |
>> |
stdout을 파일에 추가 |
2> |
stderr를 파일로 |
2>> |
stderr를 파일에 추가 |
2>&1 |
stderr를 stdout으로 |
&> |
stdout과 stderr 모두 파일로 |
입력 리다이렉션
< 기호로 파일에서 입력을 받습니다.
# 파일 내용을 명령어에 입력으로 제공wc -l < file_list.txt
8
Here Document (<<)
Here Document는 스크립트 안에 여러 줄의 텍스트를 직접 작성할 때 사용합니다. 종료 마커(보통 EOF)가 나올 때까지의 내용을 입력으로 전달합니다.
cat << EOF안녕하세요.이것은 Here Document입니다.변수도 사용할 수 있습니다: $USEREOF
안녕하세요.
이것은 Here Document입니다.
변수도 사용할 수 있습니다: ubuntu
<<'EOF'처럼 종료 마커를 따옴표로 감싸면 변수 치환 없이 그대로 출력됩니다.
cat << 'EOF'변수 치환 없음: $USEREOF
변수 치환 없음: $USER
Bash 스크립트에서 설정 파일을 자동 생성할 때 Here Document가 매우 유용합니다.
cat > /tmp/nginx_test.conf << EOFserver { listen 80; server_name localhost; root /var/www/html;}EOF
Here String (<<<)
Here String은 한 줄짜리 문자열을 명령어에 입력으로 보낼 때 사용합니다.
# bc 계산기에 수식 전달bc <<< "3 * 7 + 2"
23
# read 명령어에 문자열 전달read first last <<< "홍 길동"echo "이름: $last$first"
이름: 길동홍
/dev/null — 블랙홀
/dev/null은 쓰면 사라지고, 읽으면 즉시 EOF를 돌려주는 특수 파일입니다. 원하지 않는 출력을 버릴 때 사용합니다.
# 오류 메시지 숨기기find / -name "*.log" 2>/dev/null# 출력 전체 버리기 (실행만 되면 되는 경우)some_command &>/dev/null# 파일을 비우기 (0바이트로 초기화)> logfile.txt
Bash 스크립트에서 2>/dev/null은 매우 자주 쓰이는 패턴입니다. 사용자에게 불필요한 오류 메시지를 보이지 않게 하면서도 명령어는 계속 실행하게 해줍니다.
입출력 스트림의 흐름을 이해했다면, 이제 이 스트림들을 파이프로 연결해 명령어를 조합하는 방법을 살펴볼 차례입니다.