Skip to the content.

리눅스(Linux)나 맥(macOS) 환경에서 인프라 배포나 자동화 작업을 처리할 때 가장 먼저 찾게 되는 도구는 바로 Bash 셸 스크립트(Shell Script)입니다. 이번 포스팅에서는 셸 스크립트 파일 최상단에 붙는 #!/bin/bash의 의미와 함께, 에러 메시지를 통제하는 핵심 기법인 표준 에러 리다이렉션(2> /dev/null)의 동작 원리에 대해 자세히 다뤄보겠습니다.


1. 스크립트의 시작, 쉬뱅(Shebang: #!)

텍스트 편집기(vi, nano 등)를 이용해 셸 스크립트를 작성할 때, 첫 번째 줄에는 약속처럼 다음과 같은 문자열을 작성합니다.

#!/bin/bash

이를 쉬뱅(Shebang) 또는 해시-뱅(Hash-bang)이라고 부르며, 해당 스크립트 파일을 실행할 때 어떤 인터프리터(해석기)를 사용해 구문을 분석할 것인지 운영체제(OS)에 지시하는 선언문입니다.


2. 파일 디스크립터(File Descriptor)와 3대 스트림

리눅스 및 유닉스 계열 OS에서는 “모든 것은 파일이다”라는 대원칙 하에 입출력을 처리합니다. 프로세스가 가동되면 OS는 기본적으로 3개의 데이터 통로(스트림)를 열어주며, 이를 식별하기 위한 정수 번호를 파일 디스크립터(FD)라고 부릅니다.

파일 디스크립터 (FD) 표준 명칭 기본 목적
0 표준 입력 (Standard Input, stdin) 키보드 등의 입력 스트림
1 표준 출력 (Standard Output, stdout) 화면에 출력되는 정상적인 실행 결과
2 표준 에러 (Standard Error, stderr) 실행 중 발생하는 오류 메시지 출력

3. 에러 출력을 감추는 exec 2> /dev/null

스크립트를 백그라운드 크론탭(Crontab) 등으로 스케줄링하여 돌리다 보면, 명령 오류로 인해 화면이나 터미널 로그에 지저분한 에러 메시지가 대량으로 출력되는 것을 막아야 하는 상황이 생깁니다. 이때 활용하는 명령이 바로 리다이렉션 기호(>)와 파일 디스크립터 2번(stderr)입니다.

1) 개별 명령어 단위 제어

ls -l /nonexistent_folder 2> /dev/null

2) 스크립트 전체 제어 (exec 활용)

스크립트 내부의 매 명령어마다 2> /dev/null을 붙이는 것은 귀찮은 일입니다. 스크립트 상단에 exec 명령을 사용하면 이후 실행되는 모든 명령어에 글로벌하게 적용할 수 있습니다.

#!/bin/bash
exec 2> /dev/null # 이후 발생하는 모든 표준 에러를 화면에 출력하지 않고 폐기합니다.

# 이 명령어들은 에러가 발생해도 화면에 아무런 출력을 남기지 않습니다.
cat /invalid/path/file.txt
rm /nonexistent/file

4. 실무 권장 가이드: 에러 로깅으로 활용하기

무조건 에러를 폐기하는 2> /dev/null은 개발 단계나 디버깅 시 치명적인 결함의 원인을 추적하기 어렵게 만듭니다. 실무에서는 에러를 버리기보다 아래와 같이 에러 로그 파일로 보관하는 방식(누적 추가 >>)을 훨씬 권장합니다.

#!/bin/bash
# 표준 에러(2)를 error.log 파일에 누적 기록합니다.
exec 2>> /var/log/my_script_error.log

쉬뱅의 정확한 정의와 파일 디스크립터 기반 스트림 처리를 명확히 이해하시면, 안정적이고 제어 가능한 리눅스 인프라 제어 스크립트를 작성하실 수 있습니다.