2. 쉘의 변수

특수 변수들

파라미터 인자. $1, $2,..,$9

쉘에서 가장 중요한 컨셉은 쉘스크립트에 인자를 넘기는 것이다. $ 로 시작하면 변수를 의미한다. 그 후 숫자가 오면 인자의 순서를 의미한다. 예를 들어 $1은 첫번째 인자. $2는 두번째 인자를 의미한다. $0은 특수 인자이다.

파일 이름을 변경하는 스크립트 작성

rename a b 라는 스크립트를 작성해보자.

  • 초안
# rename0.sh
#!/bin/bash
# rename
# Usage: rename oldname newname
mv $1 $2
  • 인자가 없을 경우 디버그 메시지 출력
# rename1.sh
#!/bin/bash
# rename
# Usage: rename oldname newname
mv ${1:?"missing"} ${2:?"missing"}

$chmod +x rename1.sh
$./rename1.sh a
> ./rename1.sh: line 4: 2: missing
  • 변수 이름이 나오게 변경
# vi rename2.sh
#!/bin/bash
# rename
# Usage: rename oldname newname
oldname=$1
newname=$2
mv ${oldname:?"missing"} ${newname:?}

$chmod +x rename2.sh
$./rename2.sh
> ./rename2.sh: line 6: oldname: missing
$./rename2.sh a
> ./rename2.sh: line 6: newname: parameter null or not set

인자가 9개를 넘어갈때

$10, ${10} 은 지원되지 않는다. 9개를 넘어갈때는 shift 명령어를 사용하면된다. 인자의 첫번째 앞부분을 삭제하고 두번째를 1번에 위치 시킨다. (0 번 즉 커맨드에는 영향을 주지 않는다.)

# vi shift0.sh
#!/bin/bash
arg1=$1;shift;
arg2=$1;shift 2;
# arg3=$1;shift;
arg4=$1;shift;
arg5=$1;

echo $arg1 $arg2 $arg3 $arg4 $arg5

$chmod +x ./shift0.sh
$./shift0.sh 1 2 3 4 5
>1 2 4 5

0 - script name

0번째 파라미터는 특수 파라미터 이며 스크립트의 이름을 가지고 있다. shift 에 영향을 받지 않고 에러 보고에 사용 할 수 있다.

# vi rename.sh
...
echo $0: error
...

> rename: error

$* - 모든 위치 파라미터.

$* 의 경우 첫 번째 부터 뒤의 모든 파라미터를 리턴한다.

  • 첫 번째 인자가 목표 디렉토리이고 뒤에 움직일 N 개의 파일을 적을 수 있다.
# vi moveto.sh
#!/bin/bash
directory=$1; shift
mv $* ${directory:?} 

chmod +x moveto.sh
./moveto.sh

$@ - space 를 포함한 모든 파라미터

$*, $@는 기본적으로 같다.

다른점은 쉘스크립트안에서 $*, $@ 를 사용해 모든 파라미터를 다른 명령어로 넘길때 스페이스로 인자를 분리하냐의 여부가 다르나. 이 다른점은 사용 할 경우가 거의 없을거 같다. - 윈본

$# - 스크립트에 넘어온 인자의 수량

vi numberofargs.sh

#!/bin/bash
echo $#
shfit $# #remove all args
echo $*

chmod +x numberofargs.sh
./numberofargs.sh 1 2 '3 a'
> 3
>

$$ - 현재 프로세스 ID

유니크한 임시 파일을 만들기 위해 현재 프로세스ID를 조합해서 사용

  • 유니크 파일을 만들고 지운다.
# vi uniq.sh
#!/bin/bash
filename=/tmp/$0.$$
cat "$@" | wc -w > $filename
echo args word count is `cat $filename`
rm $filename

$echo '1 2 3' > a.txt
$chmod +x uniq.sh
$./uniq.sh a.txt
  • 자기가 쓰던 자원 정리
    • 표기된 시그널중 하나를 받으면 해당 명령어를 실행한다.
      • trap [실행될 명령어] [반응할 signals]
#!/bin/sh

trap cleanup 1 2 3 6

cleanup()
{
  echo "Caught Signal ... cleaning up."
  rm -rf /tmp/temp_*.$$
  echo "Done cleanup ... quitting."
  exit 1
}

시그널

Number SIG Meaning
0 0 On exit from shell
1 SIGHUP Signal hangup Clean tidyup
2 SIGINT Signal Interrupt (Ctrl + c)
3 SIGQUIT Quit (Ctrl + D)
6 SIGABRT Abort
9 SIGKILL Die Now (cannot be trapped)
14 SIGALRM Alarm Clock
15 SIGTERM Terminate

$! - 백그라운드 잡 process ID

백그라운드에서 실행된 프로세스의 id(& 사용) 백그라운드에서 실행 할 때만 $!의 id를 변경 한다.

  • 10초 대기 후 죽는 스크립트
    • trap 은 핸들러이기 때문에 상단에 선언해 주는게 좋다.
vi sleep10s.sh

#!/bin/bash
trap "echo @slee10s trap called" 1 2 15

echo "@Start sleep10s - $$"
sleep 5s
echo "@End sleep10s"

chmod +x sleep10s.sh
  • 자기가 죽을때 자신이 실행 시킨 백그라운드 프로세스도 죽이는 것
    • 스그널이 없으면 백그라운드가 끝나기를 기다려서 같이 죽음
vi background.sh

#!/bin/bash
./sleep10s.sh &
trap "echo trap; kill -TERM $!" 0 1 2 15

echo "@Wait"
wait $!
echo "@Dead"

chmod +x background.sh
  • Wait 명령어에 인자가 없으면 스크립트에서 실행된 모든 프로세스가 죽을때까지 대기한다.

$? 에러 값 리턴

마지막으로 실행된 스크립트의 에러 값을 리턴한다.

vi error.sh

#!/bin/bash
exit 12

vi error_report.sh

#!/bin/bash
./error.sh
echo $?
  • 원본 아래 내용은 개인용으로 정리한 내용 입니다.