반응형

 

리눅스/유닉스 쉘의 입출력 리다이렉션에서 사용되는 파일 디스크립터(File Descriptor)이 있습니다.  여기서 리다이렉션이란, 프로그램의 기본 입출력 통로를 바꾸는 행위를 말합니다. 

 

1. 파일 디스크립터 (File Descriptors)

리눅스/유닉스 시스템에서 실행되는 모든 프로그램은 기본적으로 3개의 입출력 채널을 가지며, 이 채널들은 숫자로 식별되는데 이것을 파일 디스크립터라고 부릅니다.

디스크립터 (숫자) 이름 (축약어) 용도용도
0 STDIN (Standard Input) 프로그램이 입력을 받는 채널 (일반적으로 키보드)
1 STDOUT (Standard Output) 프로그램의 일반적인 출력이 나가는 채널 (일반적으로 화면)
2 STDERR (Standard Error) 프로그램의 오류/진단 메시지가 나가는 채널 (일반적으로 화면)

자세히 얘기하면,

2는 표준 오류(STDERR)로, 시스템에서 오류 메시지를 전송하도록 약속된 고유 번호가 2입니다.

1은 표준 출력(STDOUT)로, 시스템에서 일반적인 출력을 전송하도록 약속된 고유 번호가 1입니다.

 

 

2. 기본 테스트

- test.sh

#!/bin/bash

# 1. 표준 출력으로 메시지 출력 (화면/터미널에 일반 메시지로 표시)
echo "이것은 STDOUT입니다."

# 2. 표준 에러로 메시지 출력 (오류 채널로입니다. 표시)
echo "경고! 이것은 STDERR입니다." >&2

 

실행 예 1)

./test.sh
이것은 STDOUT입니다.
경고! 이것은 STDERR입니다.​

 

실행 예 2)

./test.sh 1> a.txt
경고! 이것은 STDERR입니다.​

 

그리고 a.txt 안에는 

이것은 STDOUT입니다.

 

1> 이라고 설정하면 표준출력은 a.txt에 출력한다는 뜻입니다. 그래서 a.txt에는 쉘스크립트 안에서 표준출력으로만 출력된 내용만 있습니다. 그리고 화면에는 표준에러만 출력이 보이게 됩니다.

 

실행 예 3)

./test.sh 2> b.txt
이것은 STDOUT입니다.

그리고 b.txt 안에는

경고! 이것은 STDERR입니다.

 

2> 이라고 설정하면 표준에러는 b.txt에 출력한다는 뜻입니다. 그래서 b.txt에는 쉘 스크립트 안에서 표준에러만 출력된 내용만 있고 화면에는 표준출력만 보이게 됩니다.

 

참고)

./test.sh 2>&1 | tee asd.txt

 

위 명령어 관련해서 설명하면, 

./test.sh 명령어를 실행하고 2>&1 (리다이렉션)을 사용했습니다. 

 

1. 2>&1 (리다이렉션) 의 의미

  • 2: 표준 오류(Standard Error, STDERR, 파일 디스크립터 2번)를 의미합니다.
  • >: 리다이렉션 연산자입니다.
  • &1: 파일 디스크립터 1번(STDOUT)을 의미합니다.
  • 실제 동작은 표준 오류(2번)를 표준 출력(1번)과 같은 곳으로 리다이렉트(재지정)합니다.
    • 즉, 이 명령어가 발생시키는 오류 메시지까지도 일반 출력 스트림에 포함시키도록 만듭니다.

 즉 이 명령어는 test.sh를 실행하고 그 스크립트에서 나오는 STDOUT과 만약 발생할 수 있는 오류 메시지 (STDERR)가 하나의 출력 스트림으로 합쳐지게 됩니다.

 

2. | tee asd.txt (파이프 및 출력 복사) 의 의미

  • |: 파이프(Pipe)입니다. 앞 명령어의 STDOUT을 뒤 명령어의 STDIN(표준 입력)으로 연결합니다.
  • tee: STDIN으로 받은 내용을 두 곳으로 보냅니다.  STDOUT (화면 출력)과 지정된 파일 (asd.txt)입니다.

즉, 위 명령어의 동작은 앞서 합쳐진 스트림(test.sh에서 나오는 STDOUT + STDERR)을 tee 명령어의 입력으로 받아, 화면에도 출력하면서 동시에 내용을 asd.txt 파일에 저장합니다.

 

 

◆ 1이 아니라 &1인 이유

더보기

 이는 쉘 리다이렉션 문법에서 '파일 이름'과 '파일 디스크립터'를 구별하기 위해서 입니다.

 

일반적인 파일 리다이렉션에서는, 리다이렉션 연산자 (>) 뒤에 일반적인 숫자문자열이 오면, 쉘은 그것을 파일 이름으로 해석해버립니다.

 

예를 들면, "명령어 > 1"는 STDOUT(1)의 내용을 1이라는 이름의 파일에 쓰라는 뜻입니다.

그렇다면 &1은 파일 이름 1이 아니라, 파일 디스크립터 1번 (STDOUT)을 참조하라는 뜻입니다.

 

리다이렉션 연산자 (>, <) 뒤에 &를 붙이면, 쉘은 뒤에 오는 것이 파일 이름이 아니라 이미 열려 있는 파일 디스크립터 번호임을 알게 됩니다. 이것을 파일 디스크립터 복사라고 합니다.

 

즉, & 기호는 "이것은 파일 이름이 아니라, 참조할 파일 디스크립터 번호입니다"라고 쉘에게 알려주는 역할을 합니다. 

 

 

 

반응형