2015. 2. 26. 18:28ㆍLinux/Shell Script
출처 : https://wiki.kldp.org/wiki.php/ShellProgrammingTutorial
1. 변수
- 쉘변수는 대소문자를 구분함.
- 쉘변수는 데이터를 문자열로 저장하여, 실제 수치를 대입해도 문자열이 저장, 계산이 필요하면 자동으로 수치를 변환하여 계산후 다시 문자열로 저장.
- 쉘변수의 값을 사용할 때는 변수명 앞에 $를 붙임. //ex echo $Test
- 쉘변수의 값을 대입할 때는 $를 사용하지 않음. // name=aa -> name 변수에 "aa" 값을 대입.
- 쉘변수는 타입이 없다. //c와 비교하여 int, float, char 같은 타입에 구애 받지않고 사용이 가능함.
1.1 환경변수
-쉘을 가동하면 기본적으로 세팅되어있는 변수. 일반변수처럼 값을 얻어오거나 셋팅할 수 있다.
- $0 -> 실행된 쉘 스크립트 이름 //ex) test.sh
- $# -> 스크립트에 넘겨진 인자의 개수 // ./test.sh a1 a2 a3 a4 인자 4개를 줬을 때 $#의 값은 4
- $$ -> 쉘 스크립트의 프로세트 ID
1.2 인자변수
-쉘스크립트에 인자를 넘겨줄때 그 인자들에 대한 정보를 가지고 있는 변수
$1~$nnn -> 넘겨진 인자들
$* -> 스크립트에 전달된 인자들을 모아놓은 문자열, 하나의 변수에 저장되며 IFS 환경변수의 첫번째 문자로 구분
//ex) ./test.sh a1 a2 a3 a4
echo $* -> a1 a2 a3 a4 출력
$@ -> "$*" 과 같으나 IFS 변수의 영향을 받지 않음
//ex) ./test.sh a1 a2 a3 a4
echo $@ -> a1 a2 a3 a4 출력
2.1 연산
- 변수= expr 산술식 //ex) a= expr $a + $b
곱하기 연산은 \*으로 사용
2.2 매개변수 확장
변수의값을 문자열 등으로 대체하는 것을 말한다. 단순한 대체가 아니라 변수내 문자열을 조작하여 원하는 문자열만을 추출이 가능하다.
1 #!/bin/sh
2 3 p="/usr/X11R6/bin/startx" 4 5 unset p 6 a=${p:-"Variable p Not found"} 7 echo $a 8 9 p="/usr/X11R6/bin/startx" 10 a=${p:-"Variable parm Not found"} 11 echo $a 12 13 a=${#p} 14 echo $a 15 16 a=${p%/*} 17 echo $a 18 19 a=${p%%/*} 20 echo $a 21 22 a=${p#*/} 23 echo $a 24 25 a=${p##*/} 26 echo $a 27
Variable p Not found /usr/X11R6/bin/startx 21 /usr/X11R6/bin usr/X11R6/bin/startx startx
- 6행 : 변수 p 가 제거 되었으므로 "Variable p Not found" 가 a에 들어간다.
- 10행 : 변수 p 가 있으므로 그대로 a에 들어간다.
- 13행 : a에는 변수 p의 길이가 들어간다.
- 16행 : p 에서 가장 오른쪽의 "/"부터 끝까지 지우고 나머지를 a에 넣는다.
- 19행 : p 에서 가장 왼쪽의 "/" 부터 끝까지 지우고 나머지를 a에 넣는다. (아무것도 없다)
- 22행 : p 의 처음부터 가장왼쪽의 "/" 까지 지우고 나머지를 a에 넣는다.
- 25행 : p 의 처음부터 가장 오른쪽의 "/"까지 지우고 나머지를 a에 넣는다.
3. 조건문 if
if test -f test1
then
...
fi
test 명령을 [ ] 로 대체가 가능
if [ -f test1 ]
then
...
fi
or
if [ -f test1 ]; then
...
fi
3.1. test 명령
3.1.1. 문자열 비교
3.1.2. 산술 비교
- expr1 -eq expr2 - 두 표현식 값이 같다면 참 ('EQual')
- expr1 -ne expr2 - 두 표현식 값이 같지 않다면 참 ('Not Equal')
- expr1 -gt expr2 - expr1 > expr2 이면 참 ('Greater Than')
- expr1 -ge expr2 - expr1 >= expr2 이면 참 ('Greater Equal')
- expr1 -lt expr2 - expr1 < expr2 이면 참 ('Less Than')
- expr1 -le expr2 - expr1 <= expr2 이면 참 ('Less Equal')
- ! expr - expr 이 참이면 거짓, 거짓이면 참
- expr1 -a expr2 - expr1 AND expr2 의 결과 (둘다 참이면 참, 'And')
- expr1 -o expr2 - expr1 OR expr2 의 결과 (둘중 하나만 참이면 참, 'Or')
3.1.3. 파일 조건
- -b FILE - FILE 이 블럭 디바이스 이면 참
- -c FILE - FILE 이 문자 디바이스 이면 참.
- -d FILE - FILE 이 디렉토리이면 참
- -e FILE - FILE 이 존재하면 참
- -f FILE - FILE 이 존재하고 정규파일이면 참
- -g FILE - FILE 이 set-group-id 파일이면 참
- -h FILE - FILE 이 심볼릭 링크이면 참
- -L FILE - FILE 이 심볼릭 링크이면 참
- -k FILE - FILE 이 Sticky bit 가 셋팅되어 있으면 참
- -p FILE - True if file is a named pipe.
- -r FILE - 현재 사용자가 읽을 수 있는 파일이면 참
- -s FILE - 파일이 비어있지 않으면 참
- -S FILE - 소켓 디바이스이면 참
- -t FD - FD 가 열려진 터미널이면 참
- -u FILE - FILE 이 set-user-id 파일이면 참
- -w FILE - 현재 사용자가 쓸 수 있는 파일(writable file) 이면 참
- -x FILE - 현재사용자가 실행할 수 있는 파일(Executable file) 이면 참
- -O FILE - FILE 의 소유자가 현재 사용자이면 참
- -G FILE - FILE 의 그룹이 현재 사용자의 그룹과 같으면 참
- FILE1 -nt FILE2 - : FILE1이 FILE2 보다 새로운 파일이면 ( 최근파일이면 ) 참
- FILE1 -ot FILE2 - : FILE1이 FILE2 보다 오래된 파일이면 참
- FILE1 -ef FILE2 - : FILE1 이 FILE2의 하드링크 파일이면 참
3.3. case 구문
case 변수 in 패턴 [ | 패턴 ] ... ) 문장 ;; 패턴 [ | 패턴 ] ... ) 문장 ;; .... * ) 문장 ;; esac
3.4. 목록
3.4.1. AND 목록
statment1 && statment2 && statmentN && .....
3.4.2. OR 목록
statment1 || statment2 || statmentN || .....
3.4.3. AND와 OR목록은 혼용이 가능하다.
[ 조건 ] && 문장1 || 문장2
[조건] && { 문장1 문장2 문장3 } || { 문장4 문장5 문장6 }
4.1. for
for 변수 in 값1, 값2, ... do 문장 done
for str in "test1", "test2", "test3", "test4" do echo @str done
test1 test2 test3 test4
for file in $(ls -a | grep "^\.") do echo "$file is Hidden File" done
for file in $(ls chap[345].txt); do echo "--- $file ---" >> Books.txt cat $file >> Books.txt done
echo "\$* output" for fvar in $* do echo $fvar done echo "\$@ output" for fvar in $@ do echo $fvar done
4.2. while
while 조건문 do 문장 done
echo "Enter Password : " read password1 echo "Retype Password : " read password2 while [ "$password1" != "$password2" ] do echo "Password mismatch Try again " echo "Retype Password : " read password2 done echo "OK Password Match complete"
4.3. until
until 조건문 do 문장 done
#!/bin/sh until who | grep "$1" > /dev/null do sleep 10 done echo "User $1 just logged in ^_^"
4.4. select
#!/bin/sh echo "다음중 스크립트언어 프로그래밍에 속하는 것은 ?" select var in "쉘 프로그래밍" "C 프로그래밍" "자바 프로그래밍" "Exit" do if [ "$var" = "쉘 프로그래밍" ] then echo "정답입니다." exit 0 elif [ "$var" = "Exit" ] then echo "종료합니다." exit 1 else echo "$var 을 선택하셨습니다. 오답입니다." echo "다음중 스크립트언어 프로그래밍에 속하는 것은 ?" fi done
5. 함수
함수명 () { 문장 return 값 }
함수명 인자1, 인자2, ...
#!/bin/sh func() { echo ------ this is func -------- echo "This Script Executable File : $0" echo "Argument Count : $#" echo "Process ID : $$" echo "Argument List \$* : $*" echo "Argument List \$@ : $@" echo "Argument 1 : $1" echo "Argument 2 : $2" echo "Argument 3 : $3" } echo ------ this is main -------- echo "This Script Executable File : $0" echo "Argument Count : $#" echo "Process ID : $$" echo "Argument List \$* : $*" echo "Argument List \$@ : $@" echo "Argument 1 : $1" echo "Argument 2 : $2" echo "Argument 3 : $3" echo "Argument 4 : $4" func aa bb cc
6. 명령어
6.2. continue
while [ $a -eq 10 ] do if [ $a -eq 5 ]; then continue fi done
6.4. . 명령
6.6. eval
foo=10 x=foo y='$'$x echo $y
foo=10 x=foo eval y='$'$x echo $y
6.13. set
#!/bin/sh echo $# set $(ls) echo $#
0 22
6.14. shift
#!/bin/sh echo $1 shift echo $1 shift 5 echo $1
#./myscript 1 2 3 4 5 6 7 8 9 0 1 2 7
6.15. trap
trap command signal
7. 명령 실행
x = $(명령)
8. 쉘 스크립트 내부에서 명령에 입력 전달하기 (Here Documents)
명령 << 종료문자열 입력값..... 종료문자열
#!/bin/sh mail $1 << myscript This is Header This is Body . myscript
9.1. 쉘 옵션
- sh -n 스크립트 : 문법 에러만을 검사, 명령을 실행하지 않음
- sh -v 스크립트 : 명령을 실행하기 전에 에코
- sh -x 스크립트 : 명령줄에서 처리한 다음 에코
9.2. set 옵션
- set -o noexec 또는 set -n : 문법 에러만을 검사, 명령을 실행하지 않음
- set -o verbose 또는 set -v : 명령을 실행하기 전에 에코
- set -o xtrace 또는 set -x : 명령줄에서 처리한 다음 에코
- set -o nounset 또는 set -u : 정의되지 않은 변수가 사용되면 에러 메시지를 제공한다.
set -x for str in "test1" "test2" "test3" "test4" do echo $str done
+ for str in '"test1"' '"test2"' '"test3"' '"test4"' + echo @str @str + for str in '"test1"' '"test2"' '"test3"' '"test4"' + echo @str @str + for str in '"test1"' '"test2"' '"test3"' '"test4"' + echo @str @str + for str in '"test1"' '"test2"' '"test3"' '"test4"' + echo @str @str