DevOps/Shell

Shell Script - 8, Variable(2)

게임이 더 좋아 2022. 11. 24. 00:09
반응형
728x170

**여기선 예약된 변수에 대해 알아볼 것이다.

 

우리는 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