LINUX/리눅스 쉘 스크립트 바이블 정리

[리눅스 바이블] 15. 데이터 보여주기

은재정 2022. 3. 24. 21:37

입력 및 출력 이해하기

리눅스 시스템은 모든 개체를 파일로 다루며 파일 디스크립터를 사용하여 각 파일 개체를 식별한다.

각 프로세스는 한 번에 최대 9개의 파일 디스크립터를 열 수 있다.

 

  • 파일 디스크립터 0은 STDIN
  • 파일 디스크립터 1은 STDOUT
  • 파일 디스트립터 2는 STDERR

STDIN 파일 디스크립터는 쉘의 표준 입력을 의미한다. 터미널 인터페이스에서 표준 입력은 키보드이다.

STDOUT 파일 디스크립터는 쉘의 표준 출력을 뜻한다. 터미널 인터페이스에서 표준 출력은 모니터이다.

STDERR 파일 디스크립터는 쉘의 표준 오류 출력을 의미한다. 기본적으로 STDOUT 파일 디스크립터와 같은 곳을 가리킨다.

 

오류만 리다이렉트하기 위해서는 2> 기호를 사용한다.

정상 출력을 리다이렉트하기 위해서는 1> 기호를 사용한다.

ls -al testfile badtestfile 2> err 1> output

 

또는 오류 및 정상 출력을 모두 리다이렉트하려면 특수한 기호인 &>를 사용할 수 있다.

 

스크립트 안에서 출력 리다이렉트하기

스크립트에서 출력을 리다이렉트하는 방법으로는

 

  • 각 줄을 임시로 리다이렉트하는 방법
  • 스크립트에서 모든 명령을 지속적으로 리다이렉트하는 방법

두 가지가 존재한다. 

 

출력을 STDERR 파일 디스크립터에 리다이렉트하려면 >& 기호를 사용하고 뒤에는 파일 디스크립터 번호인 2를 붙인다.

스크립트에 리다이렉트할 데이터의 양이 많다면 exec 명령을 사용하여 한꺼번에 할 수 있다.

 

#!/bin/bash
exec 2> testerror
echo "1"
echo "2"
exec 1> testout
echo "3"
echo "4" >& 2

위 예시에서는 1, 2는 모니터에 표시되고 3은 testout 파일에, 4는 testerror 파일에 출력된다.

 

스크립트에서 입력 리다이렉트하기

 

앞에서와 마찬가지로 exec 명령을 사용하여 스크립트에서 입력을 리다이렉트할 수 있다.

#!/bin/bash

exec 0< testfile
count=1

while readline; do
    echo "LIne #$count: $line"
    count=$[ $count + 1 ]
done

 

사용자 정의 리다이렉트 만들기

미리 정의된 0-2 파일 디스크립터 이외에 3~8 까지의 숫자를 사용해서 입력 또는 출력 리다이렉트 중 하나로 활용할 수 있다.

마찬가지로 exec 명령을 사용하여 입출력 파일 디스크립터를 할당한다.

 

exec 3> test3out
echo "This should be stored in test3out file" >&3
# 파일 디스크립터 닫기
exec 3>&-

 

명령 출력 억제하기

때로는 스크립트의 출력을 모두 표시하고 싶지 않을 수 있다. 그럴때는 STDERR를 null 파일이라고 하는 특수한 파일로 리다이렉트 한다.

쉘이 null 파일로 보내는 모든 출력은 저장되지 않으며 없어진다.

ls -al > /dev/null
cat /dev/null
# 기존 파일의 데이터 없애기 (로그 지우기)
cat /dev/null > testfile

 

임시 파일 사용하기

리눅스 시스템은 임시 파일을 위해 예약된 특별한 디렉토리인 /tmp 디렉토리를 보유하고 있다.

대부분의 리눅스 배포판은 시동을 할 때 /tmp 디렉토리에 있는 파일을 자동으로 제거하도록 시스템을 구성한다.

 

mktemp 명령에서 -t 옵션을 사용해서 시스템의 임시 디렉토리에 임시 파일을 만들도록 강제한다.

#!/bin/bash

tempfile=$(mktemp -t tmp.XXXXXX)
echo "This is a test file" > $tempfile
echo "This is the second line of the test file" >> $tempfile

echo "The temp file is located at: $tempfile"
cat $tempfile

 

메시지 로깅

tee 명령을 통해 STDIN의 데이터를 STDOUT과 커맨드라인에 지정된 파일이름으로 보낸다.

tee filename 과 같은 방법으로 사용한다.

date | tee testfile
cat testfile

 

다만 tee 옵션은 기본적으로 사용할 때마다 파일에 덮어쓰기를 하므로 파일에 데이터를 추가하기 위해서는 -a 옵션을 사용해야 한다.