본문 바로가기
linux

쉘 스크립트 기초

by marble25 2023. 12. 25.

모던 리눅스 교과서 (마이클 하우센블라스) 를 읽으면서 쉘 스크립트에 대해서 짧게 나오는데, 내가 헷갈려 했던 부분이 여럿 적혀있어 이를 정리해두고자 한다.

데이터 타입

쉘은 일반적으로 모든 것을 문자열로 취급하지만 배열과 같은 일부 고급 데이터 유형은 지원한다.

os=('Linux' 'macOS' 'Windows')
echo "${os[0]}" # Linux
numberofos="${#os[@]}" # 

흐름 제어

분기와 반복도 가능하다.

if [ $a -eq $b ] ; then
	echo "yes"
fi

for afile in /tmp/* ; do
  echo "$afile"
done

for i in {1..10}; do
	echo "$i"
done

while true; do
	...
done

함수

함수를 사용하면 모듈화되고 재사용 가능한 스크립트를 작성할 수 있다. 쉘은 스크립트를 위에서 아래로 해석하므로 함수는 미리 정의 후 사용해야 한다.

sayhi() {
	echo "Hi $1"
}

sayhi "Michael"

IO

read를 이용하면 stdin에서 사용자 입력을 읽을 수 있다.

echo 대신 색상 등 출력을 세밀하게 제어할 수 있는 printf를 고려해보면 좋다.

스크립트 실행

스크립트는 실제로는 단순한 텍스트 파일이라는 점을 기억해야 한다. 확장자는 중요하지만 관행적으로 .sh를 붙인다.

  • 쉘 스크립트는 첫 행에서 #!으로 작성하는 shebang 혹은 hashbang을 이용해 인터프리터를 선언해야 한다.
  • 쉘 스크립트는 chmod +x 등을 사용해 실행 가능한 스크립트가 되어야 한다.

스켈레톤 템플릿

#!/usr/bin/env bash
set -o errexit # 오류 발생시 스크립트 실행을 중지한다.
set -o nounset # 설정되지 않은 변수는 오류로 처리한다.
set -o pipefail # 파이프 한 부분이 고장나면 전체 파이프가 고장난 것으로 간주한다.

firstargument="${1:-somedefaultvalue}" # default value

우수 사례

  • 빠르고 요란하게 실패해야 한다: 배시는 기본적으로 조용히 실패하는 경향이 있으니 아무도 모르게 실패해서는 안된다.
  • 민감 정보: 암호와 같은 민감 정보는 스크립트에 하드코딩되기보다는 사용자 입력이나 API 호출 등으로 런타임으로 제공되어야 한다. 또한, ps는 매개변수 등을 공개하기 때문에 민감 정보가 유출될 수 있음도 고려해야 한다.
  • 입력값 정리: 변수에 정상 기본값을 설정한다. 예를 들어 rm -rf “$PROJECTHOME/*” 가 드라이브를 지우는 상황을 피해야 한다.
  • 의존성 확인: 특정 도구나 명령을 사용할 수 있다고 가정하지 말아야 한다. 가능하면 대비책을 제공하자. curl을 사용할 수 없으면 wget을 제공하는 등이 있다.
  • 에러 처리: 스크립트 실패시 사용자가 실행할 수 있는 지침을 제공해야 한다.
  • 테스트: 스크립트를 lint하고 테스트한다. ShellCheck 같은 프로그램을 활용해 린트를 체크해볼 수 있다. 또한, Bats를 이용하면 테스트케이스를 지정할 수 있는 구문과 함께 배시 스크립트 형태로 테스트 파일을 작성할 수 있다.

'linux' 카테고리의 다른 글

[TIL] sed - 텍스트 스트림 에디터  (0) 2022.07.10