Post

09. 배시셸 프로그래밍

09. 배시셸 프로그래밍

1. 셸 스크립트 개요

프로그래밍 방법

프로그래밍 방법에는 작성한 프로그램을 컴파일러라는 별도의 소프트웨어를 통해 실행 파일로 변환한 후, 이를 사용 및 배포하는 방법과 실행할 때 인터프리터라는 소프트웨어를 통해 실행하는 방법이 있다. 후자를 통해 작성한 프로그램을 스크립트라고 부르며, 자바스크립트와 파이썬이 대표적인 스크립트 언어이다.


셸 스크립트의 구성요소

1
2
3
4
5
6
7
8
9
#!/bin/bash
# Comment

echo "Hello!"
echo "SHELL=$SHELL" # SHELL 변수 출력
date
exit 0

  • #!: 셸 스크립트는 #!로 시작한다. 주석이 아니라 하나의 기호로, 매직 넘버라고도 하며 이 뒤에는 스크립트를 해석하고 처리할 프로그램을 절대 경로로 지정한다.
  • # Comment: 주석
  • 명령과 구문
  • 셸 스크립트 종료: exit 명령으로 종료할 수 있다.

셸 스크립트의 작성과 실행

bash filename 또는 셸 스크립트 파일에 실행권한을 부여 한 뒤 ./filename으로 실행한다.


2. 변수 사용과 입력받기

변수의 정의와 사용

단순 변수

변수명=문자열으로 정의하고, $변수명으로 참조한다.

배열

변수명=(값1 값2 값3 ...) 으로 정의하고, 아래와 같이 참조한다.

  • ${배열명[i]}: 배열에서 i번째 원소를 참조한다. (i=0이 첫 번째 원소)
  • ${배열명[*]}, ${배열명[@]}: 배열의 모든 원소를 참조한다.
  • ${#배열명[*]}, ${#배열명[@]} : 배열의 크기를 참조한다.
  • 배열명+=(값): 배열에 원소를 추가한다.
  • 배열명[i]=값: 배열의 i번째 원소에 값을 저장한다. 기존 값을 바꾸거나 원소 추가가 가능하다.
  • unset 배열명[i]: 배열의 i번째 원소를 삭제한다.

변수 속성 선언

declare/typeset

  • 기능: 변수의 속성을 정의한다.
  • 형식: declare/typeset [옵션] 변수명
  • 옵션
    • -a: 배열로 정의한다.
    • -f: 스크립트에서 정의된 모든 함수를 출력한다.
    • -i: 정수형으로 정의한다.
    • -r: 읽기 전용으로 정의한다.
    • -x: 환경 변수로 export한다.

입력 받기

read

  • 기능: 표준 입력으로 한 줄을 읽어서 변수에 저장한다.
  • 형식: read [옵션] 변수1 변수2 ... 변수n
  • 옵션
    • -a: 읽은 내용을 배열로 저장한다.
    • -p 프롬프트: 프롬프트로 지정한 문자열을 출력하고 입력을 기다린다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ read a b c
1 2 3 4
$ echo $a
1
$ echo $b
2
$ echo $c
3 4
$ read -a l
a b c d
$ echo ${l[*]}
a b c d
$ read -p "Input:" a
Input:test
$ echo $a
test
$ 


명령행 인자 처리

스크립트를 실행할 때 인자로 값을 지정할 수 있고 이 값을 스크립트에서 처리할 수 있다. 이러한 인자들을 명령행 인자라고 한다. 명령행 인자들은 특수 내장 변수들에 저장되어 스크립트 내에서 사용할 수 있는데, 이 특수 내장 변수를 포지션 인자(Positional Parameter)라고 한다.

  • $0: 현재 셸 스크립트의 이름
  • $1 ~ $9: 명령행에 주어진 1~9번 포지션 인자
  • $#: 전체 포지션 인자 개수
  • $*, $@: 모든 포지션 인자
  • $$: 셸의 프로세스 번호
1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

echo 'Script Name: ' $0
echo '$*: ' $*
echo '$@: ' $@
echo '$1: ' $1
echo '$2: ' $2
echo '$#: ' $#
echo '$$: ' $$

1
2
3
4
5
6
7
8
9
Script Name:  test
$*: 
$@: 
$1: 
$2: 
$#:  0
$$:  431386


3. 연산자

산술 연산자

  • -: 음수, 뺄셈
  • *: 곱셈
  • /: 나눗셈
  • %: 나머지
  • +: 덧셈
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ a=1
$ echo $a
1
$ a=$a+1
$ echo $a
1+1
$ let a=$a+1 # let
$ echo $a
3
$ let a=a+1 # let
$ echo $a
4
$ declare -i b # declare
$ b=1
$ b=b+1
$ echo $b
2
$ echo $((b+1)) # (( ))
3


비교 연산자

숫자 비교 연산자 (정수)

  • 아래 조건이 참이면 0, 거짓이면 1
  • [ $a -eq b ], (( a = b )), (( a == b ))
  • [ $a -ne b ], (( a != b))
  • [ $a -gt 0 ], (( a > b ))
  • [ $a -ge 0 ], (( a >= b ))
  • [ $a -lt 0 ], (( a < b ))
  • [ $a -le 0 ], (( a <= b ))

test 명령

  • 기능: 조건식이 참인지 거짓인지 확인한다.
  • 형식: test 조건식
  • 사용 예: test a -eq b
  • 참 또는 거짓 값이 셸의 종료 상태 변수인 $? 에 저장된다.

문자열 비교 연산자

  • 두 문자열이 같으면 참: [ 문자열a == 문자열b ]
  • 두 문자열이 같지 않으면 참: [ 문자열a != 문자열b ]
  • 문자열의 길이가 0이 아니면 참 [ -n 문자열]
  • 문자열의 길이가 0이면 참 [ -z 문자열]

논리 연산자

  • 논리곱(AND): if [조건a -a 조건b], if [[ 조건a && 조건b ]]
  • 논리합(OR): if [조건a -o 조건b], if [[ 조건a || 조건b ]]
  • 논리 부정(NOT): if [ !조건 ]

파일 테스트 연산자

  • 파일이 존재: [ -a 파일 ], [ -e 파일 ]
  • 파일이 디렉터리: [ -d 파일 ]
  • 파일이 심볼릭 링크: [ -h 파일 ]
  • 파일이 일반 파일: [ -f 파일 ]
  • 파일이 읽기 가능: [ -r 파일 ]
  • 파일 크기가 0보다 큼: [ -s 파일 ]
  • 파일이 쓰기 가능: [ -w 파일 ]
  • 파일이 실행 가능: [ -x 파일 ]
  • 파일 크기가 0: [ -z 파일 ]

4. 제어문

조건문

if

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# if

if 조건식
then
  명령들
fi

# if else

if 조건식
then
  명령들
else
  명령들
fi

# if elif else

if 조건식
then
  명령들
elif
then
  명령들
else
  명령들
fi

case

조건에 따라 처리해야 할 경우가 여러 가지일 때 유용하다.

1
2
3
4
5
6
7
8
9
10
11
case $변in
  값1)
    명령;;
  값2)
    명령;;
  ...
  *)
    명령;;
esac

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/bin/bash
# case

echo -n "Input Level(1~9): "
read level

case $level in
  [7-9])
    echo "High Level";;
  [4-6])
    echo "Middle Level";;
  [1-3])
    echo "Low Level";;
  *)
    echo "Input Error";;
esac


반복문

for

리스트의 값을 순차적으로 가져와 지정한 명령을 반복하여 실행한다.

1
2
3
4
5
6
for 변수 in 리스트
do
  명령들
done

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash
# for loop

num=(80 90 100)

for n in ${num[*]}
do
  echo Num: $n
done

while

조건식의 결과가 참이면 지정된 명령을 반복적으로 수행하며, 조건식의 결과가 거짓이면 반복이 종료된다.

1
2
3
4
5
6
while 조건식
do
  명령들
done

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash

num=1
total=0
while (($num <= 100))
do
  if (($num%2 == 0))
  then let total=total+num
  fi
  let num=num+1
done
echo "Total sum: $total"


5. 함수

함수의 기본 형식

1
2
3
4
5
6
함수명()
{
  명령들
}

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
# function test

today()
{
  echo -n "Today: "
  date
}

today


함수 호출

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

today()
{
  echo -n "Today: "
  date
}

today

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash
# function test

writeNum()
{
  echo "Num: $1, $2, $3"
}

writeNum 1 2 3


6. 디버깅

배시셸의 옵션 중 -x는 스크립트가 각 행을 실행할 때마다 화면으로 출력한다. 따라서 오류가 발생한 부분을 확인할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
bash -x script15
+ num=1
+ (( 1 <= 5 ))
+ echo 'Num: 1'
Num: 1
+ let num=num+1
+ (( 2 <= 5 ))
+ echo 'Num: 2'
Num: 2
+ let num=num+1
+ (( 3 <= 5 ))
+ echo 'Num: 3'
Num: 3
+ let num=num+1
+ (( 4 <= 5 ))
+ echo 'Num: 4'
Num: 4
+ let num=num+1
+ (( 5 <= 5 ))
+ echo 'Num: 5'
Num: 5
+ let num=num+1
+ (( 6 <= 5 ))

이 예에서 +로 시작하는 행은 현재 실행 중인 스크립트의 코드이며, + 기호가 없는 문장은 echo 명령으로 출력된 부분이다.

This post is licensed under CC BY 4.0 by the author.