Shell Script

GreenBean·2021년 10월 1일
0
post-thumbnail

Shell Script

Shell Script란?

  • 셸 스크립트(shell script)셸이나 명령 줄 인터프리터에서 돌아가도록 작성되었거나 한 운영 체제를 위해 쓰인 스크립트
    • 단순한 도메인 고유 언어로 여기기도 함
    • 셸 스크립트가 수행하는 일반 기능으로는 파일 이용, 프로그램 실행, 문자열 출력 등이 있음
  • .sh라는 파일 확장자를 가진 파일이 특정 종류의 셸 스크립트를 가리키는 것이 보통이지만, 대부분의 셸 스크립트는 파일 확장자를 지니지 않음

Shell Script 장단점

장점

  • 셸 스크립트를 기록하는 것은 다른 프로그래밍 언어의 같은 코드로 쓰인 것보다 훨씬 더 빠른 경우가 많음
    • 다른 해석 언어에 비해, 셸 스크립트는 컴파일 단계가 없기 때문에 스크립트는 디버깅을 하는 동안 빠르게 실행할 수 있음

단점

  • 셸 스크립트를 사용함으로써 몇 가지 중대한 단점이 존재
    • 실행되는 각 명령에 대한 잠재적으로 새로운 하부 프로세스의 수많은 필요에 따라 속도가 느려질 수 있음
    • 단순 sh 스크립트는 다양한 종류의 유닉스, 리눅스, BSD 운영 체제, therof 버전, 시스템 유틸리티와 잘 호환된다는 장점이 있지만 더 복잡한 셸 스크립트는 셸, 유틸리티, 다른 필수 요소 간의 약간의 차이가 많은 경우 실패할 가능성이 있음
    • 이와 비슷하게, 더 많은 복잡한 스크립트들은 셸 스크립트 언어 자체의 제한 안에서 실행할 수 있음
      • 이러한 제한 때문에 다양한 셸이 문제를 개선할 목적으로 고품질의 코드와 확장을 기록하기 힘들 수 있음

Shell Script 기초

기본 설정

#!/bin/sh 

echo "Hello, World!"
  • 셸 스크립트 파일은 기본적으로 .sh 확장자로 작성
  • 실제 코드를 작성하기 전에 맨 처음의 행에는 #!/bin/sh를 씀
    • 시스템에 지금부터 셸 스크립트를 쓴다는 사실을 알려주기 위함
      • #는 hash, !는 bang이므로 #!를 shebang이라고 부르기도 함
    • bash의 독자적인 기능을 사용하는 경우 다르게 작성
      • #!/usr/bin/env bash
  • 셸 스크립트 파일(test.sh)를 실행하기 위해서는, 터미널에서 파일이 저장된 장소에 가서 아래의 커맨드 중 하나를 선택해서 실행해야 함
# 방법 1
$ chmod 755 test.sh
$ ./test.sh

# 방법 2
$ sh test.sh

# 방법 3
$ bash test.sh
  • 파일을 실행시키면, 작성한 Hello, World!가 표시됨

기본 커맨드

  • 코멘트
    • # 로 코멘트 처리할 수 있음
#!/bin/sh 
 
# 코멘트처리된 구문은 실행되지 않음

echo "Hello, World!"

입력 / 출력

  • 입력 / 출력
    • echo로 출력, read로 입력 가능
#!/bin/sh 

read NAME 
echo "Hello, $NAME!"

>>> $ ./test.sh 
>>> Hwaya
>>> Hello, Hwaya!
  • 입력을 대기하고 있는 경우, 스크립트는 실행되지 않음
    • Bash에서는 -e 플래그로 특수 텍스트를 이스케이프 할 수 있음
#!/bin/bash 
echo -e "Hello\n$NAME!"

변수

  • 변수의 이름으로써 영문자, 숫자, 그리고 언더바가 사용됨
  • 변수에 값을 전달할 때는 =앞,뒤에 공백 없이 작성
    • 문자열인 경우 "(쌍따옴표)로 감싼다.
  • 변수에 액세스할 때 변수명의 앞에 $를 넣거나 혹은 $넣어서 변수를 {}로 감쌈
  • 하나의 변수에 한 개의 값만 보존됨
  • 변수의 값이 덮어 쓰기되는 것을 방지하기 위해서는 readonly를 사용
  • 변수를 unset으로 삭제할 수 있음
    • readonly 변수를 삭제하는 것을 불가능
#!/bin/sh 

var="변수1" 
VaR_2="변수2" 
echo "Var_2=$VaR_2" 

VaR_2="VaR_2 변경" 
echo ${VaR_2} 

readonly var 
var="readonly var 변경 불가능"

>>> $ ./test.sh 
>>> Var_2=변수2 
>>> VaR_2 변경 
>>> shell.sh: line 11: var: readonly variable

특별한 변수

  • $0 : 스크립트명
  • $1 ~ $9 : 인수, 첫 번째의 인수는 $1, 2번째 인수는 $2로 액세스
  • $# : 스크립트에 전달된 인수의 수
  • $* : 모든 인수를 모아 하나로 처리
  • $@ : 모든 인수를 각각 처리
  • $? : 직전에 실행한 커맨드의 종료 값(0은 성공, 1은 실패)
  • $$ : 이 쉘 스크립트의 프로세스 ID
  • $! : 마지막으로 실행한 백그라운드 프로세스 ID
#!/bin/sh 

echo "\$0(스크립트 명): $0" 
echo "\$1(1번째 인수): $1" 
echo "\$2(2번째 인수): $2" 
echo "\$3(3번째 인수): $3" 
echo "\$#(인수의 수): $#" 
echo "\"\$*\": \"$*\"" 
echo "\"\$@\": \"$@\"" 
VAR="마지막 값은 0!" 
echo $?

>>> $ ./test.sh first second 3rd 
>>> $0(스크립트 명): test.sh 
>>> $1(1번째 인수): first 
>>> $2(2번째 인수): second 
>>> $3(3번째 인수): third 
>>> $#(인수의 수): 3 
>>> "$*": "first second third" 
>>> "$@": "first second third" 
>>> 0

특수 문자

  • * ? [ ' " ` \ $ ; & ( ) | ~ < > # % = 스페이트 탭 개행은 쉘 스크립트의 특수 문자
  • 문자열로써 사용할 때는 \를 앞에 쓴 다음에 사용

변수 값의 치환

  • ${var} : 변수 값을 바꿔 넣음
  • ${var:-word} : 변수가 아직 세팅되지 않거나 공백 문자열의 경우 word를 반환, var에는 저장되지 않음
  • ${var:=word} : 변수가 아직 세팅되지 않거나 공백 문자열의 word를 반환, var에 저장
  • ${var:?word} : 변수가 아직 세팅되지 않거나 공백 문자열의 경우 치환에 실패하고 스탠다드 에러에 에러가 표시됨
  • ${var:+word} : 변수가 세팅되지 않은 경우 word가 반환, var에는 저장되지 않음
#!/bin/sh 
echo "1 - ${var:-wordSetInEcho1}" 
echo "2 - var = ${var}" 
echo "3 - ${var:=wordSetInEcho3}" 
echo "4 - var = ${var}" 
unset var 
echo "5 - ${var:+wordSetInEcho5}" 
echo "6 - var = $var" 
var="newVarValue" 
echo "7 - ${var:+wordSetInEcho7}" 
echo "8 - var = $var" 
echo "9 - ${var:?StandardErrorMessage}" 
echo "10 - var = ${var}"

>>> 1 - wordSetInEcho1 
>>> 2 - var = 
>>> 3 - wordSetInEcho3 
>>> 4 - var = wordSetInEcho3 
>>> 5 - 
>>> 6 - var = 
>>> 7 - wordSetInEcho7 
>>> 8 - var = newVarValue 
>>> 9 - newVarValue 
>>> 10 - var = newVarValue

배열 (Bash)

#!/bin/bash 

#bash shell로 배열을 작성하는 방법 
ARRAY=(item1 item2 item3 item4) 
ARRAY[0]="ITEM1" 
ARRAY[2]="ITEM3" 

echo "ARRAY[0]: ${ARRAY[0]}" 
echo "ARRAY[1]: ${ARRAY[1]}" 

#모든 아이템에 액세스 
echo "ARRAY[*]: ${ARRAY[*]}" 
echo "ARRAY[@]: ${ARRAY[@]}"

>>> $ ./test.sh 
>>> ARRAY[0]: ITEM1 
>>> ARRAY[1]: item2 
>>> ARRAY[*]: ITEM1 item2 ITEM3 item4 
>>> ARRAY[@]: ITEM1 item2 ITEM3 item4

오퍼레이터

  • 셸에서는 산수 연산자로 expr 숫자 연산자 숫자를 이용한다.
  • 연산자
    • + : 덧셈
      • echo expr 10 + 20
        >>> 30
    • - : 뺄셈
      • echo expr 20 - 10
        >>> 10
    • \* : 제곱
      • echo expr 11 \* 11
        >>> 121
    • / : 나눗셈
      • echo expr 10 / 2
        >>> 5
    • % : 나머지
      • echo expr 10 % 4
        >>> 2
    • = : 저정
      • a=$b
      • b의 값이 a에 저장
    • == : 동일
      • [ "$a" == "$b" ]
      • $a$b가 동일하는 경우 TRUE가 반환
    • != : 다름
      • [ "$a" != "$b" ]
      • $a$b가 동일하지 않는 경우 TRUE가 반환
  • 비교
    • eq : 동일
      • [ "$a" -eq "$b" ]
      • $a$b가 동일한 경우 TRUE가 반환
    • -ne : 다름
      • [ "$a" -ne "$b" ]
      • $a$b가 동일하지 않은 경우 TRUE가 반환
    • -gt : 보다 큼
      • [ "$a" -gt "$b" ]
      • $a$b보다 큰 경우 TRUE가 반환
    • -lt : 보다 작음
      • [ "$a" -lt "$b" ]
      • $a$b보다 작은 경우 TRUE가 반환
    • -ge : 보다 크거나 같음
      • [ "$a" -ge "$b" ]
      • $a$b보다 크거나 같은 경우 TRUE가 반환
    • -le 보다 작거나 같음
      • [ "$a" -le "$b" ]
      • $a$b보다 작거나 같은 경우 TRUE가 반환
    • ! : 아님
      • [ ! "$a" -gt "$b" ]
      • $a$b보다 크지 않은 경우 TRUE가 반환
    • -o : 어느 쪽이든 (OR)
      • [ "$a" -gt "$b" -o "$a" -lt "$b" ]
      • $a$b보다 크거나 작은 경우 TRUE가 반환
      • Bash 확장 / POSIX 폐지 예정
    • -a : 양쪽 모두 (AND)
      • [ "$a" -gt 90 -a "$a" -lt 100 ]
      • $a가 90보다 크고 100보다는 작은 경우 TRUE가 반환
    • -z : 문자열이 비었는가
      • [ -z "$a" ]
      • $a에 어떤 것도 지정되지 않은 경우 TRUE가 반환
    • -n : 문자열이 차있는가
      • [ -n "$a" ]
      • $a에 어떠한 것이 지정되어 있다면 TRUE가 반환

if 조건

  • if의 기본 작성법은 if [ 조건 ] then 커맨드 fi
  • 조건과 일치하는 경우, then 뒤의 커맨드가 실행
  • 조건과 다른 경우, 차례로 elif [ 조건 ]에 적힌 내용을 확인
  • 일치하는 조건이 없는 경우, else 다음의 커맨드가 실행된 후 종료
  • else가 존재하지 않는 경우, 그대로 종료됨
#!/bin/sh 

if [ "$1" -gt "$2" ] 
then 
    echo "1번째 인수가 2번째 인수보다 크다" 
elif [ "$1" -eq "$2" ] 
then 
    echo "1번째 인수와 2번째 인수가 동일하다" 
else 
    echo "1번째 인수가 2번째 인수보다 작다" 
fi

>>> $ ./test.sh 2 7 
>>> 1번째 인수가 2번째 인수보다 작다 

>>> $ ./test.sh 10 5 
>>> 1번째 인수가 2번째 인수보다 크다 

>>> $ ./test.sh 9 9 
>>> 1번째 인수와 2번째 인수가 동일하다

switch 조건

  • switch의 기초 작성법은 case 변수 in 조건・값) 커맨드 ;; esac
  • 조건・값이 변수와 일치하는 경우, 그 곳에 적힌 커맨드가 실행
#!/bin/sh 

DRINK="coffee" 
case "$DRINK" in 
    "beer") echo "맥주입니다" 
    ;; 
    "juice") echo "주스입니다" 
    ;; 
    "coffee") echo "프로그래머가 마시면 커피로 변화!" 
    ;; 
esac

>>> $ ./test.sh 
>>> 프로그래머가 마시면 커피로 변화!

루프 (반복문)

  • 루프(반복문)에서는
    • break 키워드로 종료할 수 있고
    • continue 키워드로 현재의 루프를 건너 뛸 수 있음
  • while 루프
    • 조건과 일치할 때 반복
#!/bin/sh 

a=0 
while [ $a -lt 5 ] 
do 
    echo $a 
    a=`expr $a + 1` 
done

>>> $ ./test.sh
>>> 0
>>> 1
>>> 2
>>> 3
>>> 4
  • until 루프
    • while과 반대로 조건과 일치할 때까지 반복
#!/bin/sh 

a=0 
until [ ! $a -lt 5 ] 
do 
    echo $a 
    a=`expr $a + 1` 
done

>>> $ ./test.sh
>>> 0
>>> 1
>>> 2
>>> 3
>>> 4
  • for 루프
    • for의 기본 작성법은 for 변수 in 여러 개의 값・변수・범위 do 커맨드 done
    • 조건과 값이 변수와 일치하는 경우 커맨드가 실행
#!/bin/sh 

for var in 0 1 2 3 4
do 
    echo $var 
done

>>> $ ./test.sh
>>> 0
>>> 1
>>> 2
>>> 3
>>> 4

함수

  • 셸 스크립트에서는 함수를 작성하여 인용하는 것이 가능
#!/bin/sh 

#함수 작성
MyFunction () { 
    echo "함수의 echo이다." 
} 
MyParamFunc() { 
    echo "인수1:$1 인수2:$2" 
} 

#함수 호출
MyFunction 
MyParamFunc param1 param2

>>> $ ./test.sh 
함수의 echo입니다. 
인수1:param1 인수2:param2
profile
🌱 Backend-Dev | hwaya2828@gmail.com

0개의 댓글