쉘의 동작과 사용자 인터페이스에 영향을 미치는 변수
참고: 아주 일반적인 상황에서는 각 프로세스는 자신이 참조할 정보들을 담고 있는 변수들의 그룹인 "환경"이란 것을 갖고 있습니다. 이런 관점에서 보면, 쉘도 다른 프로세스들과 다를 바 없습니다.
쉘은 자신이 시작될 때마다 자신의 환경 변수에 대응하는 쉘 변수를 만들어 냅니다. 쉘 변수를 업데이트하거나 새롭게 추가하면 쉘은 자신의 환경 변수를 업데이트 시키고 쉘의 모든 자식 프로세스(쉘에서 실행시킨 명령어들)는 그 환경을 물려 받습니다.
경고 | |
환경용으로 할당된 공간은 제한되어 있습니다. 환경 변수를 너무 많이 만들거나 한 환경 변수가 공간을 지나치게 많이 사용한다면 문제가 생길 수 있습니다.
(명확한 설명을 해 주고 위의 예제를 제공해준 S. C. 에게 감사) |
만약에 스크립트가 환경 변수를 세트하면 그 변수는 "export"되어야 합니다. 즉, 그 스크립트에 해당하는 환경으로 보고되어야 한다는 뜻입니다. export 명령어가 이 일을 해 줍니다.
참고: 스크립트는 변수를 오직 자신의 자식 프로세스에게만 export 할 수 있습니다. 즉, 자신이 만들어낸 명령어나 프로세스들만 적용을 받습니다. 명령어줄에서 실행된 스크립트는 특정 변수를 명령어줄 환경으로 거꾸로 export 할 수 없습니다. 자식 프로세스는 자신을 만들어낸 부모 프로세스에게 특정 변수를 거꾸로 export 할 수 없습니다.
---
명령어줄에서 스크립트로 넘어온 인자들로 $0, $1, $2, $3... 이런식으로 표현되는데 $0 은 스크립트의 이름 그 자체를 나타내고 $1 은 첫번째 인자를, $2 는 두번째를, $3 은 세번째를 나타내는 식입니다. [1] $9 다음의 인자는 ${10}, ${11}, ${12} 처럼 중괄호로 묶어줘야 합니다.
예 5-5. 위치 매개변수
#!/bin/bash # 최소한 10 개의 매개변수를 줘서 이 스크립트를 실행시키세요. 예를 들면, # ./scriptname 1 2 3 4 5 6 7 8 9 10 echo echo "스크립트 이름은 \"$0\"." # 현재 디렉토리를 나타내는 ./ 가 추가되어 있죠. echo "스크립트 이름은 \"`basename $0`\"." # 경로명을 떼어 냅니다('basename' 참고). echo if [ -n "$1" ] # 테스트 할 변수를 쿼우트 해줬습니다. then echo "첫번째 매개변수는 $1" # # 을 이스케이프 시키기 위해서 쿼우트를 해 줘야 됩니다. fi if [ -n "$2" ] then echo "두번째 매개변수는 $2" fi if [ -n "$3" ] then echo "세번째 매개변수는 $3" fi # ... if [ -n "${10}" ] # $9 보다 큰 매개변수는 {중괄호}로 감싸야 됩니다. then echo "열번째 매개변수는 ${10}" fi echo exit 0 |
어떤 스크립트들은 자신이 불린 이름에 따라 다르게 동작할 수도 있습니다. 이런 식의 동작을 원한다면 스크립트 안에서 자기가 어떻게 불렸는지를 나타내는 $0을 확인하면 됩니다. 스크립트가 어떤 이름으로 불리든지 간에 $0은 그 이름을 정확하게 심볼릭 링크하고 있기 때문입니다.
작은 정보: 명령어줄 매개변수를 예상하고 있는 스크립트가 매개변수 없이 불린다면 널 값이 할당되어 원치 않는 결과를 가져옵니다. 이런 상황을 피하는 한 가지 방법은 위치 매개변수를 변수에 할당하는 문장에서 양쪽에 똑같은 아무 문자나 붙이면 됩니다.
variable1_=$1_ # 이렇게 해주면 위치 매개 변수가 비어있더라도 에러를 막아줍니다. critical_argument01=$variable1_ # 실제로 변수를 쓸 곳에서 다음처럼 해주면 에러 방지용 문자가 잘려 나갑니다. variable1=${variable1_/_/} # $variable1_ 이 "_"로 시작할 때만 부효과(Side effects)가 있습니다. # 9장에서 논의할 매개변수 치환중의 한 가지 방법을 써서 변경 패턴을 삭제해 줍니다. # 좀 더 확실한 방법은 원하는 위치 매개변수가 넘어 왔는지 테스트를 해 보는 것입니다. if [ -z $1 ] then exit $POS_PARAMS_MISSING fi |
---
예 5-6. wh, whois 도메인 네임 룩업
#!/bin/bash # ripe.net, cw.net, radb.net 중 하나의 서버에 대해서 # 'whois domain-name' 룩업을 실행 # 이 스크립트 이름을 'wh' 라고 해서 /usr/local/bin 에 넣어두세요. # 그리고 다음처럼 심볼릭 링크를 거세요. # ln -s /usr/local/bin/wh /usr/local/bin/wh-ripe # ln -s /usr/local/bin/wh /usr/local/bin/wh-cw # ln -s /usr/local/bin/wh /usr/local/bin/wh-radb if [ -z "$1" ] then echo "사용법: `basename $0` [domain-name]" exit 65 fi case `basename $0` in # 스크립트 이름을 확인해서 해당 서버를 부릅니다. "wh" ) whois $1@whois.ripe.net;; "wh-ripe") whois $1@whois.ripe.net;; "wh-radb") whois $1@whois.radb.net;; "wh-cw" ) whois $1@whois.cw.net;; * ) echo "사용법: `basename $0` [domain-name]";; esac exit 0 |
---
shift 명령어는 위치 매개변수를 왼쪽으로 한 단계씩 이동시킵니다.
$1 <--- $2, $2 <--- $3, $3 <--- $4, 등등.
원래의 $1 은 없어지지만 $0 은 바뀌지 않습니다. 위치 매개변수가 많이 필요하다면 {중괄호} 표기법으로 가능하지만(예 5-5 참고), shift 를 써서 예전 10개를 쓸 수 있습니다.
[1] | 관습적으로, 스크립트를 호출하는 프로세스는 $0 매개변수를, 호출하는 스크립트의 이름으로 세트합니다. execv 맨페이지를 참고하세요. |