지난 두 편의 BASH 셸 시리즈에서는 변수를 심도 있게 다루었는데, 많은 독자분들께 뜨거운 호응을 받았습니다. 이번 시리즈 역시 최신 정보를 바탕으로 주제를 꼼꼼하게 정리하고, 해당 주제의 핵심 관점을 놓치지 않으려 노력하고 있습니다.
이번 글은 리눅스 변수 시리즈의 마지막 편으로, 변수 치환(variable substitution)과 셸에 미리 정의되어 있는 변수들을 살펴본 뒤 이 주제를 마무리하겠습니다.
BASH 변수 치환의 기본 원리
Bash는 명령이 실제로 실행되기 전에 변수 치환을 수행합니다. 리눅스 Bash 셸은 명령을 실행하기 앞서 '$' 기호가 붙은 모든 부분을 찾아내 해당 변수의 값으로 교체하는데, 이 과정은 단 한 번만 진행됩니다.
그렇다면 변수 안에 또 다른 변수가 선언된 중첩 변수(nested variable)라면 어떻게 될까요? 아래 예제를 통해 직접 확인해 보겠습니다.
중첩 변수 실험해 보기
먼저 읽기 전용(read-only)이면서 실행 가능(executable)한 변수를 하나 선언합니다.
admin@wsxdn.com:~$ declare -rx Linux_best_website="www.tecmint.com"
변수에 저장된 값을 확인해 보겠습니다.
admin@wsxdn.com:~$ printf "%s" "$Linux_best_website" www.tecmint.com
이번에는 같은 조건의 또 다른 변수를 선언합니다.
admin@wsxdn.com:~$ declare -rx Linux_website="Linux_best_website"
현재 상황을 정리하면 두 개의 변수가 정의되어 있습니다.
- Linux_best_website : 값은 "www.tecmint.com"
- Linux_website : 값은 "Linux_best_website"
그렇다면 아래 명령을 실행하면 어떤 결과가 나올까요?
admin@wsxdn.com:~$ printf "%s" "$Linux_website"
논리적으로 생각하면 먼저 $Linux_website가 "Linux_best_website"로 치환되고, 그 결과인 "$Linux_best_website"는 다시 변수이므로 "www.tecmint.com"으로 한 번 더 치환되어 최종 출력은 다음과 같을 것이라 기대하게 됩니다.
admin@wsxdn.com:~$ printf "%s" "$Linux_website" www.tecmint.com
하지만 안타깝게도 실제 출력 결과는 Linux_best_website입니다.
그 이유는 무엇일까요? 네, 바로 Bash는 변수 치환을 한 번만 수행하기 때문입니다. 그렇다면 복잡한 스크립트나 프로그램에서 변수를 여러 번 치환해야 하는 경우에는 어떻게 해야 할까요?
eval 명령어로 중첩 변수 치환하기
바로 이럴 때 eval 명령어가 등장합니다. eval은 스크립트 내에서 변수 치환을 한 번 이상 추가로 수행해 주는 역할을 합니다. 아래 예제를 통해 그 동작 방식을 명확히 이해할 수 있습니다.
값이 10인 변수 x를 선언합니다.
admin@wsxdn.com:~/Desktop$ declare x=10
방금 정의한 변수 x의 값을 확인합니다.
admin@wsxdn.com:~/Desktop$ echo $x 10
이번에는 값이 x인 변수 y를 선언합니다.
admin@wsxdn.com:~/Desktop$ declare y=x
변수 y의 값을 확인해 보겠습니다.
admin@wsxdn.com:~/Desktop$ echo $y x
여기까지가 BASH가 변수 치환을 한 번만 수행하기 때문에 발생하는 문제입니다. 추가적인 치환 라운드가 이루어지지 않는 것이죠. 이 문제는 eval 명령어로 해결할 수 있습니다.
admin@wsxdn.com:~/Desktop$ eval y=$x
다시 변수 y의 값을 확인해 보겠습니다.
admin@wsxdn.com:~/Desktop$ echo $y 10
성공입니다! 문제가 해결되었고, eval 명령어가 승자가 되었습니다. :)
물론 eval 명령어는 대규모 스크립트 프로그램에서 매우 유용하며, 알아두면 큰 힘이 되는 강력한 도구입니다.
사전 정의된 BASH 변수 목록
마지막으로 살펴볼 내용은 BASH 사전 정의 변수(predefined variables)입니다. 목록이 길다고 겁먹지 마세요. 스크립트를 작성할 때 전체 목록을 외워야 하는 것은 아니며, 몇 가지만 기억하면 충분합니다. 학습의 일환으로 자주 사용되는 BASH 사전 정의 변수 목록을 정리해 보았습니다.
| 번호 | BASH 변수 | 설명 |
| 1 | auto_resume | 일시 중단된 작업(job)의 명령 완료 처리 |
| 2 | BASH | 셸의 경로(PATH) |
| 3 | BASH_ENV | 프로파일 파일의 이름 표시 |
| 4 | BASH_VERSION | Bash 버전 표시 |
| 5 | BASH_VERSINFO | 상세 버전 정보 표시 |
| 6 | BASH_VERSINFO[0] | 메이저 버전 번호(릴리스) |
| 7 | BASH_VERSINFO[1] | 마이너 버전 번호(버전) |
| 8 | BASH_VERSINFO[2] | 패치 레벨 |
| 9 | BASH_VERSINFO[3] | 빌드 버전 |
| 10 | BASH_VERSINFO[4] | 릴리스 상태(예: beta1) |
| 11 | BASH_VERSINFO[5] | MACHTYPE 값 |
| 12 | CDPATH | 콜론(:)으로 구분된 디렉터리 목록 |
| 13 | COLUMNS | 표준 출력에서 한 줄당 문자 수 |
| 14 | EUID | 현재 사용자의 유효 사용자 ID |
| 15 | FCEDIT | fc 명령에서 사용하는 기본 텍스트 편집기 |
| 16 | FUNCNAME | 현재 실행 중인 함수의 이름 |
| 17 | GROUPS | 사용자가 소속된 그룹 목록 |
| 18 | HISTFILE | 명령 히스토리가 저장된 파일 |
| 19 | HOME | 홈 디렉터리의 경로 |
| 20 | LINES | 표준 출력의 가로 줄 수 |
| 21 | 수신 메일을 확인할 파일의 이름 | |
| 22 | OSTYPE | 운영체제의 종류 |
| 23 | OLDPWD | 이전 작업 디렉터리 |
| 24 | PWD | 현재 작업 디렉터리 |
| 25 | RANDOM | 참조 시 임의의 난수 반환 |
| 26 | SHELL | 기본으로 사용하는 로그인 셸 |
| 27 | TIMEFORMAT | time 명령의 출력 형식 |
| 28 | UID | 현재 사용자의 ID |
사전 정의된 BASH 변수는 이 외에도 매우 많지만, 여기서는 가장 자주 사용되는 것들을 중심으로 정리했습니다.
마무리
오늘은 여기까지입니다. 다음에도 흥미로운 글로 다시 찾아오겠습니다. 그때까지 TecMint와 계속 연결되어 있어 주세요. 소중한 피드백은 아래 댓글로 남겨주시는 것도 잊지 말아주세요!