유용한 쉘 스크립트 문법
리눅스 환경에서 개발을 하다보면 다양한 이유로 쉘 스크립트를 사용하게 됩니다. 가장 흔한 이유는 빌드의 자동화 혹은 특정 어플리케이션 실행의 편의성을 높이기 위함입니다.
예를 들어 my_app
이라는 어플리케이션의 입력 변수로 -debug_level={1~4}
라는 옵션과 -detect_object={ cat, dog, people}
같은 옵션을 준다고 예를 들어보겠습니다.
이 경우 일일이 해당 옵션을 수정하는건 개발자에게 너무 큰 고욕임이 확실합니다. 따라서 아래와 같은 쉘 스크립트를 이용하면 보다 편리하게 앱을 실행시키고 디버깅 혹은 테스트를 할 수 있게 됩니다.
#!/bin/bash
APP="my_app"
OPT1="-debug_level"
OPT2="-detect_object"
if [ $# -eq 0 ]
then
echo "default mode select!"
echo "./$APP $OPT1=1 $OPT2=cat"
elif [ $# -eq 1 ]
then
echo "input debug_level=$1"
#echo "./$APP $OPT1=$1 $OPT2=cat"
./$APP $OPT1=$1 $OPT2=cat
else
echo "input debug_level=$1 detect_object=$2"
#echo "./$APP $OPT1=$1 $OPT2=$2"
./$APP $OPT1=$1 $OPT2=$2
fi
위 스크립트의 키포인트는 아래와 같습니다.
- if, elif, else, fi
- 일반적인 프로그래밍 언어와 같은 if, else 구문을 위한 키워드 입니다.
- if와 elif는 if의 키워드로써 if [ 조건 ] then 실행구문 fi 로 구성됩니다
- $# ,$1, $2
- $#은 입력 파라메터의 개수, $0 .... $N 은 입력된 순번의 파라메터를 의미합니다.
- $0는 실행 스크립트의 이름입니다.
- -eq , -ne , ==
- eq 는 equal , ne는 not equal 으로 쓰입니다.
- if 문에서 A -eq B , A -ne B 와 같은 형태로 쓰일 수 있습니다.
- 문자열의 경우 "A" == "B" 와 같이 사용할 수 있습니다.
이 외에도 아래와 같은 빌드 스크립트를 만들 수 있습니다.
#!/bin/bash
ARG1=""
APP="app*"
PROJ=""
if [ $# -eq 0 ]
then
echo "input command"
exit 0
else
ARG1="$1"
fi
# clean all binary files
if [ "$ARG1" == "clean" ]
then
rm -f $APP
exit 0
# if exist the $1.c file,
elif [ "${ARG1##*.}" == "c" ]
then
PROJ=$ARG1
APP="app_${ARG1:0:-2}"
gcc ${PROJ} -o ${APP} `pkg-config --cflags --libs gstreamer-1.0`
# or, exist the $1.cpp file
elif [ "${ARG1##*.}" == "cpp" ]
then
PROJ=$ARG1
APP="app_${ARG1:0:-4}"
g++ ${PROJ} -o ${APP} `pkg-config --cflags --libs gstreamer-1.0`
else
echo "input compile file name"
echo "${ARG1##*.}"
exit 0
fi
echo "compile ${PROJ}"
echo "create ${APP}"
위 스크립트에 대해 간단히 설명하면 ./script test.c 와 같이 입력하였을 때, 입력된 test.c 가 c 파일 혹은 cpp 파일인지 검사하여 gcc 혹은 g++을 호출한 뒤 app_test 바이너리를 생성하는 스크립트입니다.
굳이 CMake나 Make 같은 빌드 시스템이 있는데 이렇게 쓸 필요가...? 라고 할 수 있지만 다양한 방법을 알아둬서 나쁠 건 없다 라는게 개인적인 생각입니다.
사실 같은 라이브러리를 공유하는 단일 모듈 프로그램을 테스트할 때 위 스크립트를 이용하면 CMake나 Make 파일을 고치는 행위도 필요없기도 하며, 입력 변수로 파일 이름만 던져주면 되기에 저런 식으로 사용하였습니다.
다시 글의 요점으로 돌아와, 위 스크립트의 키포인트는 "${ARG1##*.}"
입니다.
"${ARG1##*.}"
에서 ##
은 앞의 ARG1
로부터 *.
와 일치하는 문자열을 제거한다는 의미를 가집니다.
더욱 간단한 예로 ABCD##A
의 리턴 값은 BCD
가 됩니다.
다만 주의할 점으로 ABCD##BC
의 경우 리턴 값은 ABCD
입니다. {A}##{B}
으로 문자열을 조회할 때 {B}
에 해당하는 문자열의 가장 앞 부분과 {A}
문자열의 가장 앞부분부터 동일한지 확인한 뒤 제거하기 때문입니다.
이 외에도 쉘 스크립트에서는 시스템 명령어를 그대로 활용할 수 있기에 간단한 자동화 스크립트를 생성하여 작업의 효율을 크게 상승 시킬 수 있습니다.
'ETC' 카테고리의 다른 글
윈도우 환경에서 VS Code + CMake 환경 구성하기 (0) | 2022.02.28 |
---|