환경변수와 특수변수
Bash를 열면 이미 수십 개의 변수가 설정되어 있습니다. 여러분이 선언하지 않았는데도 $HOME에 홈 디렉토리가 들어있고, $PATH에는 명령어 검색 경로가 있습니다. 이것이 환경변수입니다. 그리고 Bash가 자동으로 관리하는 특수변수도 있습니다. 이것들을 제대로 알면 스크립트가 훨씬 유연해집니다.
주요 환경변수
$ env | head -20
env 명령어를 실행하면 현재 설정된 환경변수 전체를 볼 수 있습니다. 자주 쓰는 것들을 정리하면 다음과 같습니다.
| 변수 | 설명 | 예시 값 |
|---|---|---|
PATH |
명령어 검색 디렉토리 목록 | /usr/local/bin:/usr/bin:/bin |
HOME |
현재 사용자의 홈 디렉토리 | /home/user |
USER |
현재 로그인한 사용자명 | ibetter |
SHELL |
현재 사용 중인 쉘 경로 | /bin/bash |
LANG |
시스템 언어 설정 | ko_KR.UTF-8 |
PWD |
현재 작업 디렉토리 | /home/user/scripts |
OLDPWD |
이전 작업 디렉토리 | /home/user |
#!/bin/bash# 새 파일: scripts/env_info.shecho "사용자: ${USER}"echo "홈 디렉토리: ${HOME}"echo "쉘: ${SHELL}"echo "현재 디렉토리: ${PWD}"echo "이전 디렉토리: ${OLDPWD:-없음}"echo ""echo "PATH 항목들:"# PATH를 콜론으로 분리해서 각 줄에 출력echo "${PATH//:/$'\n'}"exit 0
실행 결과는 다음과 같습니다.
$ bash scripts/env_info.sh
사용자: ibetter
홈 디렉토리: /home/ibetter
쉘: /bin/bash
현재 디렉토리: /home/ibetter/scripts
이전 디렉토리: 없음
PATH 항목들:
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
export — 환경변수 전달
일반 변수는 현재 쉘에서만 사용할 수 있습니다. export로 내보내면 자식 프로세스(서브쉘, 실행된 명령어 등)도 접근할 수 있습니다.
# 일반 변수는 서브쉘에서 보이지 않음local_var="나는 지역 변수"bash -c 'echo "서브쉘: ${local_var}"' # 출력 없음# export하면 서브쉘에서도 보임export exported_var="나는 환경변수"bash -c 'echo "서브쉘: ${exported_var}"' # 출력: 서브쉘: 나는 환경변수
스크립트 안에서 선언하고 바로 export할 수도 있습니다.
export APP_ENV="production"export DB_HOST="localhost"
특수변수
Bash가 자동으로 설정하는 변수들입니다. 이름을 직접 바꿀 수 없습니다.
#!/bin/bash# 새 파일: scripts/special_vars.sh# 이 스크립트를 실행할 때 인자를 넘겨주세요# 예: bash scripts/special_vars.sh 홍길동 25 서울echo "스크립트 이름: $0"echo "첫 번째 인자: $1"echo "두 번째 인자: $2"echo "세 번째 인자: $3"echo "인자 개수: $#"echo "현재 PID: $$"echo ""echo "모든 인자 (\$@):"for arg in "$@"; do echo " - ${arg}"doneecho ""echo "모든 인자 (\$*):"for arg in "$*"; do echo " - ${arg}"doneexit 0
실행 결과는 다음과 같습니다.
$ bash scripts/special_vars.sh 홍길동 25 서울
스크립트 이름: scripts/special_vars.sh
첫 번째 인자: 홍길동
두 번째 인자: 25
세 번째 인자: 서울
인자 개수: 3
현재 PID: 12345
모든 인자 ($@):
- 홍길동
- 25
- 서울
모든 인자 ($*):
- 홍길동 25 서울
특수변수를 정리하면 다음과 같습니다.
| 변수 | 의미 |
|---|---|
$0 |
스크립트 이름(경로 포함) |
$1 ~ $9 |
위치 매개변수 (첫 번째 ~ 아홉 번째 인자) |
${10} 이상 |
열 번째 이후 인자는 중괄호 필요 |
$# |
전달된 인자 개수 |
$@ |
모든 인자를 각각 별도 항목으로 |
$* |
모든 인자를 하나의 문자열로 |
$? |
직전 명령어의 종료 코드 |
$$ |
현재 스크립트의 PID |
$! |
마지막으로 백그라운드 실행한 프로세스의 PID |
$@ vs $*의 차이
인자에 공백이 포함된 경우에 차이가 드러납니다.
#!/bin/bash# 새 파일: scripts/at_vs_star.shecho "--- \$@ 사용 ---"for arg in "$@"; do echo " 항목: [${arg}]"doneecho ""echo "--- \$* 사용 ---"for arg in "$*"; do echo " 항목: [${arg}]"doneexit 0
$ bash scripts/at_vs_star.sh "첫 번째" "두 번째" "세 번째"
--- $@ 사용 ---
항목: [첫 번째]
항목: [두 번째]
항목: [세 번째]
--- $* 사용 ---
항목: [첫 번째 두 번째 세 번째]
"$@"는 각 인자를 독립된 항목으로 보존합니다. "$*"는 모든 인자를 공백으로 이어 붙여 하나의 문자열로 만듭니다. 반복문에서 인자를 처리할 때는 거의 항상 "$@"를 씁니다.
env, printenv, set 비교
환경변수를 확인하는 명령어가 여러 개라 헷갈릴 수 있습니다.
| 명령어 | 보여주는 것 | 특징 |
|---|---|---|
env |
환경변수 | 실행 환경에서 명령어도 실행 가능 |
printenv |
환경변수 | 특정 변수 하나만 볼 때 편리 |
set |
환경변수 + 쉘 변수 + 함수 | 현재 쉘의 모든 것을 보여줌 |
# 특정 변수 하나 확인printenv HOME# 변수가 환경변수인지 확인env | grep MY_VAR
set은 출력이 매우 많아서 grep과 함께 쓰는 것이 좋습니다.