쉘 스크립트의 최상단은 다음과 같은 명령어로 시작되어야 한다.
#!/bin/sh
해당 명령어는 스크립트를 실행할 쉘을 지정하는 문법이다.
이제부터 쉘 스크립트의 사용법을 간략하게 적어보고자 한다.
쉘 스크립트는 일반 함수형 프로그래밍 언어와 마찬가지로 사용할 수 있다.
가장 먼저 알아볼 것은 변수 선언 및 입출력이다.
변수 선언 및 입출력
변수 선언은 일반적으로 다음의 세 가지 경우로 나뉜다.
- 선언 시 고정값을 입력하는 방법
- 쉘 스크립트 실행 시 파라미터를 받아 사용하는 방법
- 사용자에게 직접 입력받아 사용하는 방법
가장 먼저 고정값을 이용하는 방법은 아래와 같다.
num_var=123
chr_var='123'
*이 때 = 양 옆에는 띄어쓰기가 없어야 함을 주의한다.
출력은 echo 명령어를 이용하며, 변수 앞에 $ 키워드를 붙여 출력하는 것이 문자가 아닌 변수명임을 프로그램에 명시한다.
echo $num_var
echo $chr_var
만약 시스템 명령어의 결과값이나 다른 변수의 값을 할당하고 싶다면 아래의 방법을 이용하면 된다.
sys_var_1=`echo 123`
sys_var_2=$sys_var_1
참고로 연산 값을 입력하기 위해서는 아래의 방식을 사용해야 한다.
expr_val_2=`expr 1 + 2`
*이 때 연산자와 피연산자 사이에는 띄어쓰기가 존재하여야만 한다.
쉘 스크립트의 모든 변수는 기본적으로 다른 값으로 덮어씌울 수 있다. 다만 이렇게 덮어씌워서는 안되는 값이 있다면, readonly 키워드를 이용하여 덮어쓰기를 차단할 수 있다.
Java의 final 키워드를 생각하면 쉽다.
sys_var_1=`echo 123`
sys_var_2=$sys_var_1
sys_var_1=`echo 456`
echo $sys_var_1
readonly sys_var_2
sys_var_2=`echo 456`
echo $sys_var_2
위의 문법을 실행시켜보면 readonly 키워드 할당된 변수가 수정되지 못하며 아래와 같은 에러가 발생함을 확인할 수 있다.
만약 더 이상 사용하지 않는 변수가 있다면 unset 명령어로 삭제가 가능하다.
참고로 위의 readonly 키워드가 이미 할당된 변수라면 unset을 이용한 삭제가 불가능하다.
sys_var_1=`echo 123`
sys_var_2=$sys_var_1
readonly sys_var_2
unset sys_var_1
echo $sys_var_1
unset sys_var_2
echo $sys_var_2
다음은 파라미터를 이용하여 입력을 받는 방법이다.
파라미터의 종류는 아래와 같은 것들이 사용된다.
$0 | 스크립트명 | $1~$9 | 스크립트 실행 시 파라미터 |
$# | 파라미터의 수 | $* | 파라미터를 하나의 문자열로 |
$@ | 파라미터를 리스트로 | $? | 직전에 실행한 커멘드의 종료값 (0:성공 / 1:실패) |
$$ | 스크립트의 PID | $! | 마지막으로 실행한 백그라운드 프로세스의 PID |
각 파라미터 문법의 테스트를 위해 다음과 같은 쉘 스크립트를 작성한다.
echo 스크립트명
echo $0
echo
echo '스크립트 전달 파라미터 (1, 2, 9)'
echo $1
echo $2
echo $9
echo
echo 파라미터 수
echo $#
echo
echo 전체 파라미터를 하나로
echo $*
echo
echo 파라미터를 리스트로
echo $@
echo
echo 직전에 실행한 커맨드의 종료값
echo $?
echo
echo 스크립트의 PID
echo $$
echo
echo 마지막으로 실행한 백그라운드 프로세스의 PID
echo $!
그 후 다음 파라미터를 주어 쉘 스크립트 파일을 실행하면 다음과 같은 결과를 얻을 수 있다.
./test.sh 1 2 3 4 5
마지막 변수 값 할당 방식은 사용자에게 직접 입력을 받는 방식이다.
사용법은 read 키워드를 사용하면 된다.
read input_var
조건문
여느 프로그래밍 언어처럼 쉘 스크립트 문법에도 조건문이 존재한다. 그리고 마찬가지로 if / switch (case) 문을 사용할 수 있다.
조건문에는 ==, != 등의 연산자를 사용할 수 있으며, 아래와 같이 고유의 문자형 오퍼레이터도 존재한다.
-eq | 동일 | -ne | 동일하지 않음 |
-gt | 앞이 뒤보다 큼 | -lt | 앞이 뒤보다 작음 |
-ge | 앞이 뒤보다 크거나 같음 | -le | 앞이 뒤보다 작거나 같음 |
! | 부정 | -o | or |
-a | and | -z | 변수의 길이가 0인지 확인 |
-n | 변수가 null인지 확인 |
또한 파일/디렉터리에 대해서는 다음과 같은 조건식도 사용 가능하다.
-d | 파일이 디렉터리인지 확인 | -f | 파일인지 확인 (단 디바이스 파일에는 사용되지 않음) |
-e | 파일이 존재하는지 확인 | -L | 파일이 심볼릭 링크인지 확인 |
-s | 파일의 크기가 0보다 큰지 확인 | -r | 파일을 읽을 수 있는지 확인 |
-w | 파일을 쓸 수 있는지 확인 | -x | 파일을 실행할 수 있는지 확인 |
-nt | 앞의 파일이 뒤의 파일보다 나중에 생성됐는지 확인 | -ot | 앞의 파일이 뒤의 파일보다 이전에 생성됐는지 확인 |
-ef | 앞의 파일과 뒤의 파일이 같은 파일인지 확ㅇ니 |
if는 다음 방식으로 사용이 가능하다.
if [조건]
then
...
elif [조건]
then
...
else
...
fi
예시를 위해 다음 쉘 스크립트를 돌려보자.
var_1=123
var_2=456
var_3=""
var_4=
var_5=null
if [ $var_1 == $var_2 ]
then
echo SAME
elif [ $var_1 -gt $var_2 ]
then
echo LARGER
else
echo SMALLER
fi
if [ -z $var_3 ]
then
echo var_3 length is zero
fi
if [ -n $var_3 ]
then
echo var_3 is null
fi
if [ -z $var_4 ]
then
echo var_4 length is zero
fi
if [ -n $var_4 ]
then
echo var_4 is null
fi
if [ -z $var_5 ]
then
echo var_5 length is zero
fi
if [ -n $var_5 ]
then
echo var_5 is null
fi
file1=/tmp/test
if [ -d $file1 ]
then
echo IT IS DIRECTORY
else
echo IT IS FILE
fi
다음으로 볼 것은 switch이다. switch는 case와 esac으로 감싸며 다음과 같이 사용하면 된다.
case 변수 in
조건1) ...
;;
조건2) ...
;;
esac
테스트를 위해 다음 쉘 스크립트를 돌려보면 아래의 결과를 얻을 수 있다.
var_1=123
var_2="test"
case $var_1 in
456) echo 456
;;
123) echo 123
;;
esac
case $var_2 in
"tset") echo tset
;;
"test") echo test
;;
esac
반복문
쉘 스크립트에서는 for, while, until 키워드를 이용해 반복문을 이용할 수 있다.
for, while의 경우에는 다른 프로그래밍 언어들과 큰 차이가 없다. 그저 조건이 일치하면 반복문을 실행하는 형식이다.
하지만 until은 이와 반대인데, 조건이 불일치하면 반복문이 실행되는 형식이다.
가장 먼저 볼 것은 for이다. for은 아래와 같이 사용할 수 있다.
for var in 0 1 2 3 4 5
do
echo $var
done
만약 모든 조건을 사용하지 않고 중간에 끝내고 싶거나, 혹은 중간의 특정 값을 건너띄고 싶다면 break, continue를 이용하면 된다.
for var in 0 1 2 3 4 5
do
if [ $var == 2 ]
then
break;
fi
if [ $var == 0 ]
then
continue
fi
echo $var
done
쉘 스크립트의 모든 반복문은 같은 형식으로, do와 done으로 감싸져있다.
다음은 while과 until의 사용 방법이다.
echo ===start while===
var=0
while [ $var -lt 10 ]
do
echo $var
var=`expr $var + 1`
done
echo ===end of while===
echo ===start until===
until [ $var -lt 0 ]
do
echo $var
var=`expr $var - 1`
done
echo ===end of until===
위 쉘 스크립트를 실행하면 아래와 같은 결과를 얻을 수 있다.
함수
마지막으로 다뤄볼 것은 함수이다.
쉘 스크립트는 여느 함수형 프로그래밍 언어처럼 사용이 가능하며, 공통 로직의 경우 함수로 만들어 중복 코드를 줄일 수 있다.
함수 선언에는 특정 키워드 (Javascript의 function 등)는 필요 없으며, 그냥 다음 방식으로 사용하면 된다.
함수명() {
...
}
예시를 위해 아래 쉘 스크립트를 돌려보면 다음과 같은 결과를 얻을 수 있다.
empty_function() {
echo empty function
}
add_function_param() {
echo `expr $1 + $2`
}
empty_function
add_function_param 1 2
경우에 따라 함수의 결과를 변수에 할당해야 할 수도 있는데,
이 경우 다음과 같이 사용하면 된다.
return_val=`add_function_param 1 2`
echo $return_val
'실습 > 리눅스 서버 + 스프링 부트' 카테고리의 다른 글
JPA에서 외래키 사용 (1) | 2022.12.13 |
---|---|
[Shell Script] 프로그램 실행/종료 스크립트 만들기 (0) | 2022.09.18 |
JPA 페이징 (0) | 2022.07.25 |
application.properties (yml) 암호화 (0) | 2022.07.25 |
Spring WebFlux Filter (1) | 2022.07.25 |