쉘 스크립트란?
쉘 스크립트란 간단히 말하자면 Unix커맨드등을 나열해서 실행하는 것이다. 언제 어떤 조건으로 어떠한 명령을 실행시킬 것인가, 파일을 컨텐츠를 읽어 들일 것인가, 로그 파일을 작성하는 것 등을 할 수 있다.
기본 설정
예시로 다음과 같이 test.sh 파일을 작성한다.
#!/bin/sh
echo "Hello, World!"
- 쉘 스크립트 파일은 기본적으로 .sh 확장자로 작성한다.
- 실제 코드를 작성하기 전에 맨 처음의 행에는 #!/bin/sh를 쓴다. 시스템에 지금부터 셸 스크립트를 쓴다는 사실을 알려주기 위함이다(여담이지만, #는 hash, !는 bang이므로 #!를 shebang이라고 부르기도한다). 그러나 bash의 독자적인 기능을 사용하는 경우 다르게 작성한다(#!/usr/bin/env bash).
- 쉘 스크립트 파일(test.sh)를 실행하기 위해서는, 터미널에서 파일이 저장된 장소에 가서 아래의 커맨드 중 하나를 선택해서 실행해야한다.
$ chmod 755 test.sh
$ ./test.sh
$ sh test.sh
$ bash test.sh
파일을 실행시키면, 작성한 Hello, World!가 표시된다.
기본 커맨드
코멘트
# 로 코멘트 처리할 수 있다.
#!/bin/sh
# 여기는 코멘트이다.
# 코멘트처리된 구문은 실행되지 않는다.
echo "Hello, World!"
입력/출력
echo로 출력, read로 입력할 수 있다.
#!/bin/sh
read NAME
echo "Hello, $NAME!"
실행하면 결과는 다음과 같다.
$ ./test.sh
Tensai
Hello, Tensai!
입력을 대기하고 있는 경우, 스크립트는 실행되지 않는다.
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 "\$#(인수의 수): $#"
echo "\"\$*\": \"$*\""
echo "\"\$@\": \"$@\""
VAR="exit값은0이 될 것이다."
echo $?
실행 결과는 아래와 같다.
$ ./test.sh first second 3rd
$0(스크립트 명): test.sh
$1(1번째 인수): first
$2(2번째 인수): second
$3(3번째 인수): 3rd
$#(인수의 수): 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
오퍼레이터
shell에서는 산수연산자로 `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 | 어느쪽이든 | [ "$a" -gt "$b" -o "$a" -lt "$b" ]$a가 $b보다 크거나 작은 경우 TRUE가 반환된다. (Bash 확장 / POSIX폐지 예정) |
-a | 양쪽 | [ "$a" -gt 90 -a "$a" -lt 100 ] $a가 90보다 크고 100보다는 작은 경우 TRUE가 반환된다. |
-z | 문자열이 비었는가 | [ -z "$a" ]$a에 어떤 것도 지정되지 않은 경우 TRUE가 반환된다. |
-n | 문자열이 비었는가 | [ -n "$a" ] $a에 어떠한 것이 지정되어 있다면 TRUE가 반환된다. |
위의 오퍼레이터를 사용하여 if 조건을 작성한다.
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 #범위의 작성법(Bash독자) => {0..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
참고자료
'IT > 기초 지식' 카테고리의 다른 글
[Linux] Linux의 파일, 폴더 권한 확인과 변경 (chmod) (0) | 2021.06.17 |
---|---|
[Singularity] Singularity 이미지를 생성하는 방법(Docker hub/def file) (0) | 2021.06.16 |
[Linux] vi 기초 사용법 (0) | 2021.06.10 |
[Singularity] Ubuntu 18.04에 Singularity 설치해 NGC 컨테이너 사용하기 (0) | 2021.06.10 |
[Singularity] Singularity란? (0) | 2021.05.21 |