개요
히어 도큐먼트(here document)는 컴퓨팅 분야에서 소스 코드의 한 부분을 마치 별도의 파일인 것처럼 취급하는 파일 리터럴(file literal) 또는 입력 스트림 리터럴(stream literal)을 가리키는 용어이다. 표기에 따라 히어 도큐먼트(here-document), 히어 텍스트(here-text), 히어독(heredoc, here-doc), 히어이즈(hereis), 히어 스트링(here-string), 히어 스크립트(here-script) 등으로도 불린다. 이 용어는 비슷한 문법을 사용하는 여러 줄 문자열 리터럴(multiline string literal)을 지칭하는 데에도 쓰이며, 이 경우 텍스트 안의 줄 바꿈과 들여쓰기를 포함한 각종 공백이 그대로 보존된다.
어원
명칭은 영어 "here document(여기에 있는 문서)"에서 비롯되었다. 유닉스 셸의 입력 리다이렉션 문법 < 파일이름이 "어떤 파일로부터 입력을 받는다"는 의미인 것에 대응하여, << 뒤에 지정한 구분자까지의 텍스트를 "여기(here)에 적힌 문서(document)처럼" 표준 입력으로 사용한다는 동작 방식에서 유래한 것으로 설명된다.
역사
히어 도큐먼트는 유닉스 셸에서 기원하였으며, 1979년의 본 셸(Bourne shell) 이래로 존재하였다고 알려져 있다. 이후 sh, csh, tcsh, ksh, bash, zsh 등 대부분의 유닉스 계열 셸에서 지원된다.
문법과 동작
유닉스 셸에서 기원한 가장 일반적인 문법은 다음과 같다.
<<연산자 뒤에 구분 식별자(delimiting identifier)를 쓴다. 관례적으로EOF나END가 자주 사용된다.- 다음 줄부터 인용할 텍스트가 시작된다.
- 텍스트는 같은 구분 식별자만 단독으로 놓인 줄에 의해 닫힌다.
이 문법은 히어 도큐먼트가 형식상 스트림 리터럴이기 때문에 성립하는 것으로, 히어 도큐먼트의 내용은 선행 명령의 표준 입력(stdin)으로 리다이렉트되는 경우가 많다. 셸의 입력 리다이렉션 문법 < 파일이름과 구조적으로 유사하다. 리다이렉션 연산자와 구분 식별자 사이에는 공백이 없어도 되고 있어도 동작한다(<<EOF와 << EOF).
기본 동작은 큰따옴표로 묶은 문자열의 내용과 대체로 동일하여, 변수 이름이 그 값으로 치환되고 백틱(`) 안의 명령이 평가되는 등 매개변수 확장·명령 치환·산술 확장이 일어난다. 구분 식별자의 일부를 인용(작은따옴표 등)하면 이러한 확장이 억제되며, 이때의 동작은 내용을 작은따옴표로 묶은 것과 본질적으로 같다. 큰따옴표를 구분자에 사용할 수도 있으나, 큰따옴표 문자열에서는 확장이 일어나는데 큰따옴표로 인용한 구분자의 히어 도큐먼트에서는 확장이 일어나지 않아 혼동을 일으킬 수 있다는 점이 지적된다. POSIX 셸에서는 << 뒤에 하이픈을 붙인 <<-를 사용하면 내용 각 줄 앞부분의 탭 문자가 무시되므로, 스크립트의 들여쓰기를 유지한 채 히어 도큐먼트를 작성할 수 있다(csh/tcsh는 해당하지 않는 것으로 기술된다).
히어 스트링
히어 스트링(here string)은 문법적으로 유사하나 <<< 연산자를 사용하며, 한 개의 단어(일반적으로 문자열 리터럴)로부터의 입력 리다이렉션을 수행한다. bash, ksh, zsh 등에서 사용할 수 있다. 구분 식별자를 사용하지 않는다는 점, 그리고 선행·후행 줄 바꿈이 있으면 그대로 포함된다는 점에서 히어 도큐먼트와 구별된다. bc <<< 2^10과 같이 짧은 입력을 받는 명령에 특히 유용하며, 현재 프로세스에서 실행되어야 하는 read 빌트인 등에 활용된다.
활용
여러 줄의 텍스트를 명령의 표준 입력으로 전달하거나, 파일 내용을 생성하거나, 원격 호스트에 대한 SSH 명령 실행, 데이터베이스에 대한 SQL 질의 전달, 설정 파일 생성 등에 널리 사용된다. 파일로 출력할 때는 cat << EOF > 파일과 같이 출력 리다이렉션과 함께 쓴다.
여러 언어에서의 지원
히어 도큐먼트 양식의 문자열 리터럴은 유닉스 셸의 영향을 받은 여러 고급 언어에서도 찾을 수 있다.
- Perl: 유닉스 셸의 영향을 받은 문법을 사용하며, 구분자를 큰따옴표·작은따옴표·백틱으로 감싸는 것에 따라 변수 보간 여부와 실행 여부가 달라진다. 5.26 버전부터는 들여쓰기를 포함할 수 있는
<<~문법이 추가되었다. - PHP: 히어독(heredoc)이라 부르며, 큰따옴표 문자열처럼 동작한다. 구분자를 작은따옴표로 감싼 형태는 나우독(nowdoc)이라 한다.
- Ruby: 큰따옴표 문자열로 취급되어
#{}를 통한 보간이 가능하며,<<-및 공통 들여쓰기를 제거하는<<~문법을 제공한다. - JavaScript: 6판(ES6)에서 추가된 템플릿 리터럴(template literal)을 통해 유사한 기능을 지원한다.
- Java: 15 버전부터 텍스트 블록(text block, JEP 378)을 지원한다.
- C++: C++11부터 사용자 정의 구분자를 갖는 원시 문자열 리터럴을 지원한다.
- D:
q"식별자형태의 히어 도큐먼트 양식 문자열을 지원한다. - Racket:
#<<로 시작하는 히어 스트링을 지원한다. - PowerShell: 히어 스트링(here-string)이라 부르며,
@"·@'로 시작해"@·'@로 끝난다. - Python, Julia, Tcl: 히어 도큐먼트와는 다른 방식으로 여러 줄 문자열 기능을 제공한다.
- YAML: 공백 들여쓰기 기반의 접힘(folded,
>) 및 리터럴(literal,|) 블록 스칼라로 유사한 기능을 제공한다.
이 밖에 IBM의 JCL에서는 //SYSIN DD * 형태의 인라인 데이터로, OpenVMS의 DCL에서는 $로 시작하지 않는 입력 줄 또는 DECK 명령으로, Microsoft NMAKE에서는 인라인 파일(inline file)로 유사한 기능이 구현되어 있다. Perl과 Ruby는 __DATA__(Perl) 또는 __END__(Ruby) 이후의 내용을 파일 객체로 사용할 수 있는 데이터 세그먼트 기능도 제공하는데, 이는 히어 도큐먼트와 의미상 유사하나 스크립트당 하나만 둘 수 있다는 차이가 있다. 또한 주요 웹 브라우저가 지원하는 data: URI 역시 히어 도큐먼트의 한 형태로 설명되기도 한다.
참고 사항
히어 도큐먼트는 유닉스 셸 및 여러 프로그래밍 언어에서 널리 쓰이는 확립된 개념이며, POSIX/SUS 표준과 각 언어의 공식 문서에 정의가 존재한다. 다만 "히어 스트링"이라는 용어가 셸의 <<< 연산자를 가리키는 경우와 PowerShell·Racket 등의 다중 행 문자열을 가리키는 경우처럼, 언어와 문맥에 따라 지칭하는 대상이 달라질 수 있다. 또한 구문과 실제 기능의 세부 사항은 언어마다 상당한 차이가 있을 수 있다.
출처
- 위키백과 "히어 도큐먼트"(한국어) 및 "Here document"(영어)
- POSIX/SUS 표준 셸 명령 언어(Shell Command Language) 정의
- GNU Bash 참조 매뉴얼 3.6.6 Here Documents, 3.6.7 Here Strings
- Advanced Bash-Scripting Guide(Mendel Cooper), Chapter 19 Here Documents
- 각 언어(PHP, Ruby, Perl, Java, PowerShell 등) 공식 문서