cat << EOF > test.sh
"내용"
..(중략)..
EOF
이런 형식의 명령어를 봐왔을 것입니다. 바로 Heredoc 구문입니다. 이 Heredoc 구문을 사용하는데 자그마한 문제가 하나 있었습니다.
오늘은 제가 겪었던 문제에 관해 한번 이야기해보고자 합니다.
0. 목차
1. Heredoc이란?
2. cat << EOF 사용 시 변수에 값이 제대로 들어가지 않는 문제
3. 해결방법
..(3-a) 구분자에 따옴표 붙이기 (EOF 대신 "EOF" 사용)
..(3-b) 변수 사용 시 $앞에 이스케이프 문자(\) 붙이기
4. 결론
5. 참조
1. Heredoc이란?
여러분은 다음과 같은 형식의 명령어를 본 적이 있으실 겁니다.
명령어 << 구분자
내용 1
내용 2
..
내용 N
구분자
이러한 구문을 Heredoc이라고 하는데, Heredoc은 여러 줄의 문자열을 명령에 전달하기 위해서 사용하는데 쓰입니다.
구분자로는 보통 아무 문자가 와도 되지만 EOF를 주로 사용합니다.
2. cat << EOF 사용 시 변수에 값이 제대로 들어가지 않는 문제 (Heredoc 사용 시 발생한 문제)
그럼 이제 제가 겪었던 문제에 관해 이야기해보고자 합니다.
vim이나 nano는 설치가 필요한 경우가 많았지만, cat << EOF를 사용한 방법은 별도의 설치가 필요 없어 외부에서 만든 텍스트 파일을 붙여 넣을 때 종종 사용하곤 했습니다.
하지만 쉘스크립트를 이 방식으로 붙여 넣기 할 경우, 문제가 생겼습니다.
바로 변수를 선언하고 값을 할당해 줌에도 불구하고 변수에 아무런 값도 할당이 되지 않았습니다.
간단한 예시를 보여주도록 하겠습니다.
cat << EOF
A=apple
echo &A
EOF
해당 명령을 실행한 결과, 다음과 같이 아무것도 출력이 되지 않는 것을 확인할 수 있었습니다.
왜 이런 문제가 발생하나 한번 확인을 해보니 Heredoc의 특성을 제대로 이해하지 못한 채 사용을 하여 생긴 문제였습니다.
Heredoc을 사용할 때, 내부에 변수가 오면 변수를 확장하는 기능이 있습니다. 즉, 변수 그대로가 아닌 해석을 해서 값을 구해 치환한다고 보시면 됩니다.
이해가 되지 않으시다면 아래 쉘을 확인해 보시면 이해가 빠르실 겁니다.
분명 $A를 넣었는데 아무런 값도 없다는 것을 확인할 수 있습니다.
이는 변수 확장이 일어나 생긴 문제이며, 쉘 입장에서 A는 현재 시점에서 선언되지 않았기에 아무것도 들어가지 않은 것입니다.
만약에 해당 cat << EOF > test.sh 이전에 변수 A에 값이 할당되어 있었다면 할당된 값으로 나타날 것입니다.
한번 확인해 보도록 하겠습니다. 이번엔 test.sh을 작성하기 전에 변수 A에 banana라는 값을 할당하도록 하겠습니다.
다음과 같은 결과가 나옵니다.
실행결과에서도, cat으로 내용을 확인하였을 때에도, $A라는 문자대신 이전에 선언된 변수의 값인 banana가 들어옴을 알 수 있습니다.
쉘스크립트를 cat << EOF로 간단하게 쓰고 싶으신 분들에게는 해당 문제가 골칫거리일 텐데,
이를 방지하기 위해선 몇 가지 해결책 몇 가지를 소개해보도록 하겠습니다.
3. 해결방법
3-a. 구분자에 따옴표 붙이기 (EOF 대신 "EOF 사용)
Heredoc 자체로도 변수확장 기능을 제어가 가능합니다. 구분자를 따옴표로 묶어주면 내용들은 문자열처럼 처리되어 변수 확장은 일어나지 않습니다.
확인결과 $A가 확장되지 않고 문자 그대로 들어감을 알 수 있습니다.
3-b. 변수 사용 시 $앞에 이스케이프 문자(\) 붙이기
혹은, $앞에 이스케이프(\)를 붙여주어 $를 문자 그대로 저장하도록 하여 변수확장을 방지할 수 있습니다.
이 경우에도 $A가 확장되지 않고 문자 그대로 들어감을 알 수 있습니다.
4. 결론
cat << EOF로 쉘스크립트를 작성할 때 흔히 겪을 수 있는 실수에 관해 다뤄보았습니다.
변수 확장을 원하지 않으면 구분자(EOF)를 따옴표로 묶거나,
$앞에 이스케이프 문자(\)를 붙여주면 손쉽게 해결이 가능합니다.
쉘스크립트 작성 시 이점을 유념하시길 바라며 다른 분들은 저와 같은 실수를 하지 않도록 이 글을 남깁니다.
Heredoc과 관련해 조금 더 궁금한 사항이 있으시다면 아래 링크를 참고해 주시면 감사하겠습니다.
5. 참조
Stack overflow - How to cat <<EOF >> a file containing code?
https://stackoverflow.com/questions/22697688/how-to-cat-eof-a-file-containing-code
https://www.gnu.org/software/bash/manual/bash.html#Here-Documents
Bash Reference Manual
This chapter describes how to use the GNU History Library interactively, from a user’s standpoint. It should be considered a user’s guide. For information on using the GNU History Library in other programs, see the GNU Readline Library Manual. 9.1 Bash
www.gnu.org
https://tldp.org/LDP/abs/html/here-docs.html
Here Documents
#!/bin/bash # Another 'cat' here document, using parameter substitution. # Try it with no command-line parameters, ./scriptname # Try it with one command-line parameter, ./scriptname Mortimer # Try it with one two-word quoted command-line parameter, # ./sc
tldp.org
'프로그래밍' 카테고리의 다른 글
[원격 데스크톱]한/영 키가 안될 때 Powertoys를 이용한 해결법(키매핑) (4) | 2025.06.20 |
---|---|
[티스토리][GA]애널리틱스 집계 누락 원인 파악 및 해결 방법 (8) | 2025.06.13 |
[리눅스].desktop 파일이란? - 실행가능한 바로가기 만들기 - 우분투 24.04 (0) | 2025.04.01 |
[우분투]분수 스케일링 사용 시 VSCode 흐림 현상 해결하기 - Ubuntu 24.04 LTS (0) | 2025.03.28 |
[우분투]분수 스케일링 사용 시 크롬 흐림 현상 해결하기 - Ubuntu 24.04 LTS (0) | 2025.03.26 |