트랙
/
Bash
Bash
/
학습 과정
/
히어 도큐먼트
히어

히어 도큐먼트 에서 Bash

{other: "%{count}개의 연습 문제"}

히어 도큐먼트 소개

Bash 스크립트에서 "히어 도큐먼트"(또는 "히어독")는 여러 줄의 입력을 명령이나 프로그램으로 리다이렉션해요. 마치 터미널에 직접 입력하듯이요. 외부 파일이나 복잡한 문자열 조작 없이 스크립트 안에 여러 줄의 텍스트를 넣을 수 있는 강력한 도구죠.

주요 특징과 문법

  1. 구분자: 히어독은 << 연산자 뒤에 구분자 단어(흔히 "마커"나 "종료자"라고 불러요)를 붙여서 시작해요. 이 구분자는 원하는 아무 단어나 써도 되지만, 보통은 명확성을 위해 EOF, END, TEXT 같은 걸 사용해요. 코드를 더 읽기 쉽게 만들고 싶다면 END_INSTALLATION_INSTRUCTIONS처럼 의미 있는 단어를 구분자로 쓸 수 있어요.

  2. 내용: 맨 앞의 << DELIMITER 뒤에 리다이렉션하려는 내용을 써요. 여러 줄의 텍스트일 수도, 코드일 수도, 그 밖의 무엇이든 될 수 있어요.

  3. 종료: 구분자 단어가 앞뒤 공백 없이 그 줄에 홀로 다시 나타나면 히어독이 끝나요.

기본 문법

command << DELIMITER
  Content line 1
  Content line 2
  ...
  Content line N
DELIMITER

동작 방식

  • Bash는 시작 << DELIMITER와 끝 DELIMITER 사이의 모든 줄을 읽어요.
  • Bash는 이 내용을 명령의 표준 입력에 연결해요.
  • 명령은 이 입력을 마치 키보드에서 들어온 것처럼 처리해요.

예제 1: 간단한 텍스트 출력

cat << EOF
This is the first line.
This is the second line.
This is the third line.
EOF

출력:

This is the first line.
This is the second line.
This is the third line.

이 예제에서:

  • cat은 명령이에요.
  • << EOF는 EOF를 구분자로 히어독을 시작해요.
  • 세 줄의 텍스트가 내용이에요.
  • EOF가 홀로 한 줄에 있으면 히어독이 끝나요.
  • 그러면 cat이 받은 내용을 출력해요.

예제 2: wc와 함께 사용하기 (단어 수 세기)

wc -l << END
Line 1
Line 2
Line 3
END

출력:

3

여기서 wc -l은 줄 수를 세요. 히어독이 세 줄을 입력으로 제공하는 거예요.

예제 3: 스크립트에 데이터 전달하기

스크립트:

#!/usr/bin/env bash

# Script to process input
while IFS= read -r line; do
  echo "Processing: $line"
done

대화형 bash 프롬프트에서 히어독으로 스크립트를 호출해 봐요:

./your_script << MY_DATA
Item 1
Item 2
Item 3
MY_DATA

출력:

Processing: Item 1
Processing: Item 2
Processing: Item 3

변형과 고급 기능

리터럴 내용

Bash는 히어독 안에서 변수 확장, 명령 치환, 산술 확장을 수행해요. 그런 점에서 히어독은 큰따옴표로 묶은 문자열처럼 동작해요.

cat << EOF
The value of HOME is $HOME
The current date is $(date)
Two plus two is $((2 + 2))
EOF

출력:

The value of HOME is /home/glennj
The current date is Thu Apr 24 13:47:32 EDT 2025
Two plus two is 4

구분자를 따옴표로 묶으면(작은따옴표나 큰따옴표를 쓰면) 이런 확장이 일어나지 않아요. 내용이 그대로 해석되죠. 작은따옴표로 묶은 문자열과 비슷해요.

cat << 'EOF'
The value of $HOME is not expanded here.
The result of $(date) is not executed.
Two plus two is calculated by $((2 + 2))
EOF

출력:

The value of $HOME is not expanded here.
The result of $(date) is not executed.
Two plus two is calculated by $((2 + 2))

앞쪽 탭 문자 제거하기

<< 대신 <<-(뒤에 하이픈이 붙은 형태)를 쓰면, Bash가 히어독의 각 줄에서 앞쪽 _탭 문자_를 모두 제거해요. 이 기능은 출력에는 영향을 주지 않으면서 스크립트 안에서 히어독 내용을 들여쓰기할 때 유용해요.

# Note, the leading whitespace is tab characters only, not spaces!
# The ending delimiter can have leading tabs as well.
cat <<- END
	This line has 1 leading tab.
	  This line has a leading tab and some spaces.
		This line 2 leading tabs.
	END

출력할 때는 앞쪽 탭이 모두 제거된 상태로 인쇄돼요:

This line has 1 leading tab.
    This line has a leading tab and some spaces.
This line 2 leading tabs.
Caution

글쓴이는 이 사용법을 권하지 않아요. 스크립트의 가독성을 높여 줄 수는 있지만,

  1. 탭 문자를 실수로 공백으로 바꾸기 쉬워요(편집기가 자동으로 그렇게 할 수도 있어요). 그리고
  2. 공백과 탭의 차이를 알아보기가 어려워요.

히어 도큐먼트를 언제 사용할까요

  • 여러 줄 입력: 명령에 여러 줄의 텍스트를 제공해야 할 때.
  • 설정 파일: 스크립트 안에 작은 설정 조각을 넣을 때.
  • 코드 생성: 스크립트 안에서 즉석으로 코드를 만들 때.
  • 스크립트 상호작용: 대화형 프로그램에 사용자 입력을 흉내 낼 때.
  • 외부 파일 피하기: 임시 파일을 만들고 싶지 않을 때.

전형적인 사용 예로는 도움말 텍스트를 제공하는 경우가 있어요:

#!/usr/bin/env bash

usage() {
    cat << END_USAGE
Refresh database tables.

usage: ${0##*/} [-h|--help] [-A|--no-archive]

where: --no-archive flag will _skip_ the archive jobs
END_USAGE
}

# ... parsing command line options here ...

if [[ $flag_help == "true" ]]; then
  usage
  exit 0
fi

있을 수 있는 단점

  • 문서를 크게 넣으면 코드를 읽기 어려워질 수 있어요. 스크립트와 문서를 별도 파일로 나눠서 배포하는 편이 나을 수 있죠.
  • 히어 도큐먼트는 코드의 흐름을 끊을 수 있어요. 프로그램에 텍스트를 전달하고 싶은데 코드가 깊이 중첩된 부분에 있을 수도 있죠. 히어독의 들여쓰기가 주변 코드와 어울리지 않아 어색해 보일 수 있어요.

히어 스트링

히어 도큐먼트와 마찬가지로, 히어 스트링(또는 "히어스트링")도 명령에 입력을 제공해요. 다만 히어독은 텍스트 덩어리로 주어지는 반면, 히어스트링은 하나의 문자열로 주어져요. 히어 스트링은 <<< "text" 문법을 사용해요.

tr 'a-z' 'A-Z' <<< "upper case this string"

출력:

UPPER CASE THIS STRING

히어독과 달리 종료 구분자가 필요 없어요.

히어 스트링을 왜 사용할까요?

히어 스트링 대신 파이프라인을 사용할 수도 있어요:

echo "upper case this string" | tr 'a-z' 'A-Z'

그럼 왜 히어 스트링을 사용할까요?

오래 걸리는 계산의 출력으로 문자열을 얻었고, 그 결과를 서로 다른 두 명령에 전달하고 싶다고 해봐요. 파이프라인을 사용하면 그 계산을 두 번 실행해야 해요:

some_long_running_calculation | first_command
some_long_running_calculation | second_command

더 효율적인 방법은 (명령 치환을 사용해) 계산의 출력을 담아 두고, 히어 스트링으로 뒤따르는 두 명령에 입력을 제공하는 거예요:

result=$( some_long_running_calculation )
first_command <<< "$result"
second_command <<< "$result"

이 예제를 실무에 적용한 사례를 볼까요:

  • 페이지네이션되는 REST API 쿼리에 대한 JSON 응답을 받아 오기,
  • 그 JSON 데이터를 jq 프로그램에 넘겨 결과를 파싱하고 파일로 출력하기, 그리고
  • 그 JSON 데이터를 다른 jq 프로그램에 넘겨 다음 쿼리의 URL 알아내기.
# initialize the output CSV file
echo "ID,VALUE" > data.csv

url='https//example.com/api/query?page=1'

while true; do
  json=$( curl "$url" )

  # convert the results part of the response into CSV
  jq -r '.results[] | [.id, .value] | @csv' <<< "$json"

  # get the URL for the next page
  url=$( jq -r '.next_url // ""' <<< "$json" )
  if [[ "$url" == "" ]]; then
    break
  fi
done >> data.csv

출력 리다이렉션이 놓인 위치를 눈여겨보세요. while 루프의 모든 출력이 data.csv 파일에 이어서 추가돼요.

리다이렉션으로서의 히어독과 히어스트링

이들은 그저 리다이렉션의 한 형태일 뿐이라서, 다른 리다이렉션 연산과 함께 조합할 수 있어요:

cat <<< END_OF_TEXT > output.txt
This is my important text.
END_OF_TEXT

awk '...' <<< "$my_var" >> result.csv

정리

히어 도큐먼트(또는 "히어독")는 Bash 스크립트에서 여러 줄 입력을 다루는 유연하고 편리한 방법이에요. 스크립트 안에 텍스트와 데이터를 직접 넣는 과정을 단순하게 만들어 줘서, 스크립트가 더 자족적이고 읽기 쉬워져요.

히어 스트링(또는 "히어스트링")은 히어 도큐먼트와 비슷하지만, 더 단순하고 유연한 문법을 제공해요.

GitHub에서 편집 링크가 새 창이나 탭에서 열려요