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 $?
- 원본 아래 내용은 개인용으로 정리한 내용 입니다.