츌처 : http://www.insford.com/wiki/Wiki.jsp?page=Shell%20Script

 

들어가며#

Shell Script란?#

쉘스크립트에 대한 다음백과사전의 정의를 보면 다음과 같이 작성되어 있다.
쉘에서 사용되는 명령어들의 조합으로 구성되고 운영 체제의 명령 해석기에 의해 실행되는 스크립트. 유닉스 계열의 Bourne 쉘, C 쉘, Korn 쉘에 사용되는 스크립트들이 대표적이다. 운영 체제에 따라서는 명령어들을 파이프(|), 리다이렉션(>), 필터 등으로 연결하여 좀 더 복잡한 결과를 수행시킬 수 있는데, 이런 방식으로 묶여진 명령어 조합이 반복적으로 사용된다면 이를 쉘 스크립트화 하여 단일 명령처럼 사용하거나, 문자열을 명령어에 부가해 두고 쉘 스크립트를 독립 변수(argument)로서 넘겨줄 수도 있다.

간단하게 얘기하자면 쉘에서 명령어를 이용하여 여러가지 작업들을 처리할 수 있는데, 동일한 작업들이 반복적으로 일어나게 된다면 매번 같은 명령어를 직접 입력하지 않고 파일에 기록하여 편리하게 이용하는것이 쉘스크립트 입니다.

쉘스크립트 에디터 이클립스 플러그인#

막상 사용을 해보니까 별로네요, vi편집기에서 그냥 하는게 좋은 것 같습니다. ㅋㅋ

참고내용 URL#

쉘 프로그래밍 시작하기#

쉘 스크립트 작성#

쉘 스크립트는 기본적으로 vi에디터를 이용하여 작성한다. 아직 vi에디터에 익숙하지 않다면 다음 링크를 확인하자. 자주쓰는 vi에디터 명령어

상단부분은 항상 #! 으로 시작한다. #! 뒤에는 해당스크립트를 실행할 인터프리터의 절대경로와 실행옵션을 지정한다. 보통 #!/bin/bash, #!/bin/sh, #!/bin/csh 등을 많이쓴다.

그 외 기본 명령어들

명령어 설명
#텍스트 주석
clear 화면 지우기
echo 텍스트 or 변수 화면에 텍스트 출력
  • 샘플

#!/bin/bash # 주석입니다. clear echo Hello World #하나의 라인에서 2개의 명령어 실행 때에는 ; 구분하여 사용한다. date;echo date

echo 커맨드옵션#

echo [옵션]] [텍스트, 변수 등]]

옵션

  1. -n 출력 후 줄바꿈 안함
  2. -e 다음과 같은 문자를 텍스트에서 사용 가능하게한다.
\a alert (bell)
\b backspace
\c suppress trailing new line
\n new line
\r carriage return
\t horizontal tab
\ \ backslash

사용자 변수#

기본적으로 변수명=값 와 같은 형태로 작성한다.
  • 변수명에 값을 할당할때 공백을 넣지 않는다.
  • 대소문자를 구분한다.
  • 변수명에 ? * 문자는 사용금지
  • 샘플

#!/bin/bash test=testValue1 test2=$test test3=testValue3 echo test=$test echo test2=$test2 echo test3=$test3
  • 변수명과 텍스트를 붙여쓰고싶을때
    echo "텍스트"$변수명"텍스트"

시스템변수#

변수명 설명
BASH 쉘이름
BASH_VERSION 쉘 버젼
COLUMNS 컬럼
LINES 라인
HOME 홈디렉토리
LOGNAME 로그인명
OSTYPE OS타입
PATH 패스설정값
PS1 prompt설정값
PWD working디렉토리
SHELL 쉘이름
USERNAME 현재피씨로로그인한유저

계산식 사용하기#

expr 값1 연산자 값2

해당 공식을 계산해서 화면에 출력한다.

expr 1 + 3
expr 2 - 1
expr 10 / 2
expr 20 % 3
expr 10 \* 3
echo `expr 6 + 3`
  • 변수에 넣거나, 화면에 계산값을 출력할 때에는 ` 을 이용하여 작성한다. 키보드에 `는 ~표시와 같은위치에 있다.

sum=`expr 1 + 5` echo $sum echo `expr 5 + 1` # 계산값이 출력 됨. echo expr 5 + 1 # 이부분은 다음과 같이 그대로 출력된다. "expr 5 + 1"

quote 출력규칙#

" \, $ 문법이 사용 가능하다.
' \, $ 문법을 무시하고 그대로 출력한다.
` `안에있는 커맨드를 실행하여 출력한다.
  • 샘플

id=insford echo "Hello $id" # Hello insford 출력 echo 'Hello $id' # Hello $id 출력 echo 'expr 1 + 3' # expr 1 + 3 출력 echo `expr 1 + 3` # 4 출력

종료상태#

echo $?

위 명령어를 실행하면 최근에 실행했던 명령어의 종료상태를 알 수 있다.

0 - 성공

1~255 - 실패

  • 샘플

#!/bin/bash expr 1 + 3 echo $? # 성공이므로 0이 출력 exprrr 1 + 3 echo $? # command not found인 127이 출력된다.

에러코드에 대한 내용은 다음 링크를 참조하자 http://tldp.org/LDP/abs/html/exitcodes.html

입력값 받기#

read 변수

사용자로부터 입력값을 받는 명령어이다.

  • 샘플

#!/bin/bash echo "input your name" read name echo "your name is $name"

매개변수#

함수를 호출할 때나, 쉘스크립트파일을 실행할 때 뒤에 띄어쓰기로 구분하여 매개변수를 전달 할 수 있다.

예제 설명
$0 쉘스크립트이름
$# 매개변수의 개수
$* 매개변수들을 모아놓은 문자열
$1 ~ $n 매개변수

다음과 같이 매개변수 전달 했을 경우 #] sh xxxx.sh param1 param2


#!/bin/bash echo $0 # xxxx.sh echo $# # 2 echo $* # param1 param2 echo $1 # param1 echo $2 # param2

 

변수 내용 조작하기#

예제 설명
${variable:-default} 변수가존재하지 않으면 default로 대체한다.
${#variable} variable의 length를 얻는다.
${variable%word} variable의 끝에서부터 word와 첫번째로 일치하는 부분을 제거한다.
${variable variable의 끝에서부터 word와 마지막으로 일치하는 부분을 제거한다.
${variable#word} variable의 시작에서부터 word와 첫번째로 일치하는 부분을 제거한다.
${variable##word} variable의 시작에서부터 word와 마지막으로 일치하는 부분을 제거한다.

word에는 와일드카드(*) 를 사용할 수 있다.


#!/bin/bash abc="I am a boy" echo ${abc:-default} # I am a boy echo ${abcd:-default} # default - abcd변수가 없어서 default가 출력된다. echo ${#abc} # 10 echo ${abc%a*} # I am echo ${abc%%a*} # I echo ${abc#*a} # m a boy echo ${abc##*a} # boy

 

구조적 프로그래밍#

조건절 입력 ( test 명령 )#

if문 등에서의 조건절에서 참과 거짓을 구분할 때 test 명령이 다음과 같은 형태로 쓰인다.
    문자열비교
    test "aa" = "aa"

test명령은 [ 명령 ] 과 같은 형태로 사용할 수 있다.

    [ "aa" = "aa" ]

AND 와 OR 조건은 다음과 같은 형태로 사용이 가능하다.

    [ "aa" = "aa" ] && [ "bb" = "bb" ]
    [ "aa" = "aa" ] || [ "bb" = "bb" ]
  • 문자열 비교 조건
설명
[ string ] 빈문자열이 아니면 true
[ string1 = string2 ] 문자열이 같으면 true
[ string1 != string2 ] 문자열이 다르면 true
[ -n string ] 문자열이 null이 아니면 true
[ -z string ] 문자열이 null이면 true
  • 산술 비교 조건
설명
[ expr1 -eq expr2 ] 두 표현식이 같으면 true
[ expr1 -ne expr2 ] 두 표현식이 같지 않으면 true
[ expr1 -gt expr2 ] expr1 > expr2 이면 true
[ expr1 -ge expr2 ] expr1 >= expr2 이면 true
[ expr1 -lt expr2 ] expr1 < expr2 이면 true
[ expr1 -le expr2 ] expr1 <= expr2 이면 true
[ ! expr ] true이면 false, false이면 true
[ expr1 -a expr2 ] expr1 AND expr2 의 결과
[ expr1 -o expr2 ] expr1 OR expr2 의 결과
  • 파일 비교 조건
설명
[ -b FILE ] FILE 이 블럭 디바이스이면 true
[ -c FILE ] FILE 이 문자 디바이스이면 true
[ -d FILE ] FILE 이 디렉토리이면 true
[ -e FILE ] FILE 이 존재하면 true
[ -f FILE ] FILE 이 존재하고 정규파일이면 true
[ -g FILE ] FILE 이 set-group-id 파일이면 true
[ -h FILE ] FILE 이 심볼릭 링크이면 true
[ -L FILE ] FILE 이 심볼릭 링크이면 true
[ -k FILE ] FILE 이 Sticky bit 가 셋팅되어 있으면 true
[ -p FILE ] True if file is a named pipe.
[ -r FILE ] 현재 사용자가 읽을 수 있는 파일이면 true
[ -s FILE ] 파일이 비어있지 않으면 true
[ -S FILE ] 소켓 디바이스이면 true
[ -t FD ] FD 가 열려진 터미널이면 true
[ -u FILE ] FILE 이 set-user-id 파일이면 true
[ -w FILE ] 현재 사용자가 쓸 수 있는 파일(writable file) 이면 true
[ -x FILE ] 현재사용자가 실행할 수 있는 파일(Executable file) 이면 true
[ -O FILE ] FILE 의 소유자가 현재 사용자이면 true
[ -G FILE ] FILE 의 그룹이 현재 사용자의 그룹과 같으면 true
[ FILE1 -nt FILE2 ] FILE1이 FILE2 보다 새로운 파일이면 ( 최근파일이면 ) true
[ FILE1 -ot FILE2 ] FILE1이 FILE2 보다 오래된 파일이면 true
[ FILE1 -ef FILE2 ] FILE1 이 FILE2의 하드링크 파일이면 true

if문#


#!/bin/bash if [ 조건 ] then #조건이 참일때 else #조건이 거짓일때 fi # # if - elseif if [ 조건1 ] then #조건1 참일때 elif [ 조건2 ] #조건1이 거짓이고, 조건2가 참일때 else #조건1, 2가 거지일때 fi

case문#


case $1 in "a" ) echo '$1 is a' ;; # $1이 a일때 "b" ) echo '$1 is b' ;; # $1이 b일때 * ) echo 'do not have condition' ;; # * 이므로 $1이 어떤것이라도 출력된다. java의 default: 같음 esac

for문#

for i in 리스트

list="a1 a2 a3 a4" for i in $list do echo $i # a1, a2 .. 값이 차례대로 출력된다. done # 다음처럼 리스트에 명령어 결과를 이용 있다. for file in `ls -a` do echo $file done

while문#


i=1 while [ $i -lt 10 ] # 조건절 i < 10 이면 do echo $i i=`expr $i + 1` # i = i + 1 done

 

Functions#

쉘 스크립트에서는 다음과 같이 함수를 만들어 사용할 수 있다.


#!/bin/bash test_function() #함수명() { echo "test functions" echo "arg1=$1" # 함수를 호출할때 인자값을 입력하여 함수 내에서 사용이 가능하다. return 0; # 함수 내에서 리턴값을 사용 가능하다. 0 ~ 255 까지의 (0일경우 성공을 나타낸다) } test_function 1 # 함수를 호출하면서 1이라는 인자값을 입력하였다. echo "return=$?" # 리턴값 출력

 

  • 결과는 다음과 같다.
[insford1@j64-003 ~]$ sh test.sh 
test functions
arg1=1
return=0

다음과 같은 방법으로도 함수선언이 가능하다.


#!/bin/bash function test_function { # function 함수명 echo "test_function" local LOCAL_V="local variable" #변수선언시 앞에 local 붙이면 해당 함수 내에서만 쓰는 변수가 생성된다. V="variable" echo "test_function LOCAL_V=$LOCAL_V" echo "test_function V=$V" } test_function echo "LOCAL_V=$LOCAL_V" # local로 선언되었기 때문에 여기서는 출력이 되지 않는다. echo "V=$V"

 

  • 결과확인
[insford1@j64-003 ~]$ sh test.sh 
test_function
test_function LOCAL_V=local variable
test_function V=variable
LOCAL_V=
V=variable

디버깅 방법#

쉘스크립트 디버깅 방법을 소개합니다. 일단 예제소스를 먼저 보시면..

# 에러발생스크립트 i=1 while [ $i -lt 10 ] do echo $i i=`$i + 1` # 에러지점 i=`expr $i + 1` 과같이 사용해야한다. done

위 스크립트를 실행하면 다음과 같이 에러메세지가 발생합니다.

1
test.sh: line 8: 1: command not found
test.sh: line 5: [: -lt: unary operator expected

1까지만 출력이되고 덧셈을 하려할 때 에러가납니다.

라인만 가지고는 정확히 어느부분에서 에러가나는지 확인하는게 쉽지 않습니다. 하지만 스크립트를 실행할 때 다음과 같은 옵션을 주면 디버깅이 쉬워집니다.

옵션 설명
-v 에러메세지가 발생한 라인을 출력한다.
-x 각각의 명령이 일어나는 부분을 출력하여준다.
  • -v 옵션으로 실행하였을 때 #] sh -v xxxx.sh
i=1
while [ $i -lt 10 ]
do
        echo $i
        i=`$i + 1`
done
1
$i + 1
test.sh: line 8: 1: command not found
test.sh: line 5: [: -lt: unary operator expected

스크립트의 소스코드 및 출력값이 나오고 맨 마지막에 에러난 라인이 나와 에러가 난 부분의 소스를 확인이 가능하다.

  • -x 옵션으로 실행하였을 때 #] sh -x xxxx.sh
+ i=1
+ '[' 1 -lt 10 ']'
+ echo 1
1
++ 1 + 1
test.sh: line 8: 1: command not found
+ i=
+ '[' -lt 10 ']'
test.sh: line 5: [: -lt: unary operator expected
순차적으로 명령이 일어난 부분을 출력해주어, 1 + 1 을 계산할 때 에러가나고, 조건절에서 에러가 나는 것을 알 수 있다.

두 옵션을 적절히 사용하면 디버깅에 많은 도움이 될 듯 싶다.

+ Recent posts