Computer >> 컴퓨터 >  >> 프로그래밍 >> Bash 프로그래밍

쉘 스크립팅에서 Heredoc 사용하는 방법: 기본 구조부터 실전 활용까지

Here document(Heredoc)는 하나의 특수한 코드 블록처럼 취급되는 입력값 또는 파일 스트림 리터럴입니다. 이 코드 블록은 명령어에 전달되어 처리됩니다. Heredoc은 UNIX 셸에서 유래했으며, sh, tcsh, ksh, bash, zsh, csh 등 주요 Linux 셸에서 사용할 수 있습니다. 나아가 Perl, Ruby, PHP 같은 프로그래밍 언어에서도 heredoc을 지원합니다.

Heredoc의 기본 구조

Heredoc은 두 개의 꺾쇠 괄호 (<<)와 그 뒤에 오는 구분자(delimiter token)로 시작합니다. 동일한 구분자 토큰이 코드 블록의 끝을 나타내며, 구분자 사이에 있는 모든 내용이 하나의 코드 블록으로 간주됩니다.

아래 예제를 살펴보겠습니다. 코드 블록을 cat 명령어로 리다이렉트하고 있으며, 여기서 구분자는 "BLOCK"으로 설정되고 같은 "BLOCK"으로 종료됩니다.

cat << BLOCK
	Hello world
	Today date is $(date +%F)
	My home directory = ${HOME}
BLOCK

참고: 블록을 시작할 때와 종료할 때 반드시 동일한 구분자 토큰을 사용해야 합니다.

여러 줄 주석(Multiline Comments) 작성하기

bash로 코딩을 해본 경험이 있다면, bash가 기본적으로 CJava처럼 여러 줄 주석을 지원하지 않는다는 점을 알고 있을 것입니다. 이때 Heredoc을 활용하면 이러한 제약을 우회할 수 있습니다.

물론 이것은 bash가 여러 줄 주석을 공식적으로 지원하는 기능이 아니라 일종의 트릭(hack)입니다. heredoc을 어떤 명령어로도 리다이렉트하지 않으면 인터프리터는 단순히 코드 블록을 읽기만 할 뿐 아무것도 실행하지 않습니다.

<< COMMENT
	This is comment line 1
	This is comment line 2
	This is comment line 3
COMMENT
쉘 스크립팅에서 Heredoc 사용하는 방법: 기본 구조부터 실전 활용까지

공백(White Space) 처리하기

기본적으로 heredoc은 공백 문자(탭, 스페이스)를 제거하지 않습니다. (<<) 뒤에 대시(-)를 추가하고 구분자를 붙이면 이 동작을 바꿀 수 있습니다. 이렇게 하면 탭 공백은 모두 제거되지만, 일반 스페이스 공백은 제거되지 않습니다.

cat <<- BLOCK
This line has no whitespace.
  This line has 2 white spaces at the beginning.
    This line has a single tab.
        This line has 2 tabs.
            This line has 3 tabs.
BLOCK
쉘 스크립팅에서 Heredoc 사용하는 방법: 기본 구조부터 실전 활용까지

변수 및 명령어 치환

Heredoc은 변수 치환을 지원합니다. 변수는 사용자가 직접 정의한 변수일 수도 있고 환경 변수일 수도 있습니다.

TODAY=$(date +%F)
	
cat << BLOCK1
# User defined variables
Today date is = ${TODAY}
#Environ Variables
I am running as = ${USER}
My home dir is = ${HOME}
I am using ${SHELL} as my shell
BLOCK1

마찬가지로 heredoc 코드 블록 안에서는 어떤 명령어든 실행할 수 있습니다.

cat << BLOCK2
$(uname -a) 
BLOCK2
쉘 스크립팅에서 Heredoc 사용하는 방법: 기본 구조부터 실전 활용까지

특수 문자 이스케이프(Escaping)

특수 문자를 이스케이프하는 방법에는 여러 가지가 있습니다. 개별 문자 단위로 처리할 수도 있고, 문서 전체 단위로 처리할 수도 있습니다.

개별 특수 문자를 이스케이프하려면 백슬래시(\)를 사용합니다.

cat << BLOCK4
$(uname -a)
BLOCK4

cat << BLOCK5
Today date is = ${TODAY}
BLOCK5

블록 안의 모든 특수 문자를 한 번에 이스케이프하려면 구분자를 작은따옴표나 큰따옴표로 감싸거나, 구분자 앞에 백슬래시를 붙이면 됩니다.

cat << 'BLOCK1'
I am running as = ${USER}
BLOCK1

cat << "BLOCK2"
I am running as = ${USER}
BLOCK2

cat << \BLOCK3
I am running as = ${USER}
BLOCK3
쉘 스크립팅에서 Heredoc 사용하는 방법: 기본 구조부터 실전 활용까지

Heredoc 실전 활용 예제

이제 heredoc의 구조와 작동 방식을 이해했으니 몇 가지 실용적인 예제를 살펴보겠습니다. heredoc이 실무에서 가장 많이 활용되는 두 가지 사례는 SSH를 통해 원격 서버에서 명령어 블록을 실행하는 것과, SQL 쿼리를 heredoc으로 전달하는 것입니다.

아래 예제는 SSH를 통해 원격 서버에서 코드 블록을 실행하는 방법을 보여줍니다.

쉘 스크립팅에서 Heredoc 사용하는 방법: 기본 구조부터 실전 활용까지

다음 예제에서는 select 문을 psql에 전달하여 데이터베이스에 연결하고 쿼리를 실행합니다. 이는 bash 스크립트 안에서 -f 플래그로 .sql 파일을 실행하는 대신, psql에서 직접 쿼리를 실행할 수 있는 편리한 대안입니다.

#!/usr/bin/env bash

UNAME=postgres
DBNAME=testing

psql --username=${UNAME} --password --dbname=${DBNAME} << BLOCK
SELECT * FROM COUNTRIES
WHERE region_id = 4;
BLOCK
쉘 스크립팅에서 Heredoc 사용하는 방법: 기본 구조부터 실전 활용까지

여기까지가 이번 글의 전체 내용입니다. 예제에서 소개한 것 외에도 heredoc으로 할 수 있는 일은 무궁무진합니다. heredoc을 활용한 유용한 팁이나 노하우가 있다면 댓글로 공유해 주세요. 많은 독자들에게 큰 도움이 될 것입니다.