**여기선 예약된 변수에 대해 알아볼 것이다.
우리는 variable 중에서 ${x} $ 뒤에 오는 기호에 대해서 먼저 알아볼 것이다.
$0은 프로그램의 basename이라고 부른다.
$1…$9는 9개의 파라미터다.
$@은 모든 parameter를 지칭한다.
$*은 @와 비슷하지만 whitespace, quoting을 전혀 보존하지 않는다.
다시 말해서 "File with spaces" 라면 "File" "with" "spaces" 3개로 된다.
$#은 파라미터의 숫자를 말한다.(parameter가 몇개인지)
솔직히 말로만 하면 잘 이해가 안된다.
예시를 보자
var3.sh
#!/bin/sh
echo "I was called with $# parameters"
echo "My name is $0"
echo "My first parameter is $1"
echo "My second parameter is $2"
echo "All parameters are $@"
과연 실행시키면 어떤 값이 나오게 될까??
$ /home/steve/var3.sh
I was called with 0 parameters
My name is /home/steve/var3.sh
My first parameter is
My second parameter is
All parameters are
$
$ ./var3.sh hello world earth
I was called with 3 parameters
My name is ./var3.sh
My first parameter is hello
My second parameter is world
All parameters are hello world earth
1번째 실행에는 argument로 넣어준 것이 없다.
2번째 실행에는 hello, world, earth 3개를 넣어줬다.
똑같이 $0 에서는 자기 자신 스크립트가 나왔으며
하지만 basename이 어떻게 호출되었느냐에 따라 다르게 출력되었다.
같은 파일을 가리키지만 call을 어떻게 했냐에 따라
/home/steve/var3.sh
./var3.sh
$1에서는 빈 문자열 또는 넣어준 1번째 argument 나왔고
$@에서는 모든 parameter 들이 나왔다.
???? 9개 넘는 파라미터는 인식을 못하나..?
아니다.
shift 커맨드로 할 수 있다.
var4.sh
#!/bin/sh
while [ "$#" -gt "0" ]
do
echo "\$1 is $1"
shift
done
쉘스크립트는 shift를 사용해서 $#이 zero까지 내릴 수 있다.
즉, parameter를 다 옆으로 밀어서 순서대로 실행하는 것이다.
1까지 내려오고 옆으로 밀어서 0(base_name)이 되면 parameter는 끝났으니까 while 문을 나간다.
또 특수한 변수가 있는데
$? 라는 것이다.
$? 는 마지막으로 실행한 exit code를 담고 있다.
#!/bin/sh
/usr/local/bin/my-command
if [ "$?" -ne "0" ]; then
echo "Sorry, we had a problem there!"
fi
이 스크립트는 처음에
/usr/local/bin/my-command 라는 것을 실행하게 되는데
성공하면 exit code를 0 아니면 그 외의 것을 반환해야 한다.
이런 변수를 $?로 담아서 직접 사용할 수 있다.
$? 는 마지막으로 작동한 커맨드라는 점 때문에 변수 이름에 종속되지 않는 장점이 있다.
다음은 $$ 와 $!이다.
이건 프로세스와 관련된 변수들이다.
$$는 현재 쉘의 PID를 말한다.
이것은 임시 파일만들 때 유용하게 쓰인다.
/tmp/my-script.$$
처럼 쓰인다.
스크립트 자체가 여러 인스턴스에서 다중으로 실행될 때 유용하다.
자체적으로 임시파일이 필요할 때가 많아서 그렇다.
$!는 가장 마지막으로 background에서 실행된 프로세스(명령) PID이다.
이것은 이 프로세스 이전에 무슨 작업을 했는지 tracking 할 때 유용하다.
IFS라는 변수도 있다.
Internal Field Separator 의 약자다.
Input을 구별하는 단위이다.
Deafult 값은 (SPACE TAB NEWLINE) 다.
csv처럼 콤마를 기준으로 나눌 수도 있다.
예시를 보자면
var5.sh
#!/bin/sh
old_IFS="$IFS"
IFS=:
echo "Please input some data separated by colons ..."
read x y z
IFS=$old_IFS
echo "x is $x y is $y z is $z"
실행해보자
$ ./ifs.sh
Please input some data separated by colons ...
hello:how are you:today
x is hello y is how are you z is today
?? 뭐야 그냥 그대로 나온거 아니여???
아니다. 공백이 아닌 3개로 구분된 이유는 :로 구분하기 때문이다.
다른 입력으로 다시 보자.
$ ./ifs.sh
Please input some data separated by colons ...
hello:how are you:today:my:friend
x is hello y is how are you z is today:my:friend
???? :로 구분된다며????
하지만 우린 3개를 입력받았기 때문에 뒤에 today 부터는 다같이 입력받은 것이다.
이번엔 다른 종류의 Variable을 배워보자
아래를 보면 당연한 말을 써놨다.
foo=sun
echo $fooshine # $fooshine is undefined
echo ${foo}shine # displays the word "sunshine"
하지만 대괄호가 여기에만 쓰이는 것은 아니다.
variable이 null 이거나 undefined 라도 다룰 수 있는 방법을 알아보자
Default value를 지정하는 방법이다.
name.sh
#!/bin/sh
echo -en "What is your name [ `whoami` ] "
read myname
if [ -z "$myname" ]; then
myname=`whoami`
fi
echo "Your name is : $myname"
-en 옵션은 e옵션과 n옵션이 합쳐진 것인데
-e 문자열에서 역슬래시(\)와 조합되는 이스케이프 문자(escape sequence)를 인용부호(")로 묶어 인식
-n 마지막에 따라오는 개행 문자(newline) 문자를 출력하지 않음
를 의미한다.
실행해보면??
\n만 넣음
steve$ ./name.sh
What is your name [ steve ]
Your name is : steve
foo를 넣음
steve$ ./name.sh
What is your name [ steve ] foo
Your name is : foo
오히려 더 편하게 쉘에서는”-:” 을 사용할 수 있다.
다시 말해서 직접 default를 지정할 수 있다.
echo -en "What is your name [ `whoami` ] "
read myname
echo "Your name is : ${myname:-`whoami`}"
myname이 없으면 뒤에 값을 이용한다는 뜻이다.
이제 실제로 default 값이 될 것을 넣으면
echo "Your name is : ${myname:-John Doe}"
'DevOps > Shell' 카테고리의 다른 글
Shell Script - 10, Function (0) | 2022.11.25 |
---|---|
Shell Script - 9, External Program (0) | 2022.11.25 |
Shell Script - 7, Case (0) | 2022.11.24 |
Shell Script - 6, Test (0) | 2022.11.24 |
Shell Script - 5, Loop (0) | 2022.11.23 |