[Linux 셸 스크립트] 변환처리 - 021 미정의 변수를 에러로 처리해서 실수 방지하기
본문 바로가기
IT 이야기/Linux 셸 스크립트

[Linux 셸 스크립트] 변환처리 - 021 미정의 변수를 에러로 처리해서 실수 방지하기

by 찬찬이 아빠 2021. 3. 11.
반응형
  1. 사용 명령어

(1) set

 

  2. 키워드 & 사용처

(1) 키워드

미정의, 변수, 에러, 빈 문자열

 

(2) 사용처

스크립트에서 정의 안 된 변수를 사용하면 에러 종료하고 싶을 때 사용합니다.

 

  3. 실행 예제
./set-u.sh
./set-u.sh: line 7: COP_DIR: unbound variable

 

 

  4. 스크립트

#!/bin/sh

set -u           

 

COPY_DIR=/myapp/work

 

# COPY_DIR이 아니라 COP_DIR이라고 실수함

cp myapp.log $COP_DIR

 

 

  5. 해설

이 스크립트는 변수명을 잘못 타이핑해서 미정의 변수를 쓰게 될 때 에러를 표시하는 예제입니다. 실행하면 "unbound variable" 이라는 에러가 표시됩니다.

 

보통 셸 스크립트에서는 선언되지 않은 변수를 사용해도 에러가 발생하지 않습니다. 변수 대입으느 변수 자체를 선언하지 않아도 가능하고, 미정의 변수를 참조하면 빈 문자열이 됩니다. 따라서 일일이 변수 선언을 하지 않아도 간단하게 프로그래밍이 가능하다는 점이 셸 스크립트 장점입니다.

 

하지만 변수 선언이 필요 없다는 셸 스크립트의 특징은 생각치 못한 버그를 만들 위험이 있습니다. 예를 들어 rm 명령어로 삭제할 경로명을 셸 변수로 지정할 때 조심해야 합니다.

 

아래의 예제는 셸 변수 dirname으로 지정한 /mysapp/work/tmpdir 디렉터리를 삭제하는 스크립트 예입니다.

#!/bin/sh

dirname=/myapp/work/tmpdir
rm -rf $dirname/

 

하지만 이 스크립트는 만약 $dirname 부분을 실수해서 $dirnam 같이 작성해버리면 셸 변수 dirnam은 정의되지 않았으므로 빈 문자열이 되어 다음과 같이 실행됩니다.

rm -rf /

 

위 명령은 /(루트 디렉터리)를 지우려는 시도이므로 시스템 전체가 파손되는 중대한 문제가 발생할 수도 있습니다. 이렇듯 변수명을 잘못 기입해서 해당 위치가 빈 문자열이 되어서 그 결과 생각하지 못한 파일을 삭제하는 일은 종종있는 버그로 치명적인 결과로 이어지기도 합니다.

 

이런 일을 방지하기 위해 에서 set 명령어의 -u 옵션을 사용합니다. set -u를 지정하면 스크립트 내부에서 미정의 변수를 참조하려고 할 때 에러가 발생해서 셸 스크립트 실행이 중단됩니다. 미정의 변수를 사용하는 명령어의 실행을 막게 됩니다.

 

rm 명령어 같은 위험한 동작을 하는 셸 스크립트를 만들 때에는 set -u를 기본으로 설정해서 변수명이 정의되지 않으면 에러가 발생하도록 합시다.

 

  6. set -u 부작용

set -u 부작용은 명령행 인수 $1 같은 걸 다루기 힘들어진다는 것입니다. 다음은 명령행 인수를 표시하는 단수한 스크립트입니다.


#!/bin/sh

 

set -u

 

echo "1st arg: $1"

echo "2nd arg: $2"


 

만약 set -u 옵션을 사용하지 않으면 지정되지 않은 명령행 인수는 참조 시 빈 문자열이 되므로 실행 결과는 아래와 같습니다.

$ ./arg-set.sh 1
1st arg: 1
2nd arg:

 

그러나 이 스크립트는 set -u가 있으므로 명령행 인수가 하나뿐이면 $2가 미정의 변수가 되어 다음과 같은 에러가 발생합니다. 이를 방지하려면 셸 스크립트 내부에서 명령행 인수가 몇 개인지 계산해서 처리해야 합니다.

$ ./arg-set.sh 1
1st arg: 1
./arg-set.sh: line 5: $2: unbound variable

 

셸 스크립트에서 명령행 인수를 자주 다루므로 편리성을 위해 자주 set -u를 생략합니다. 뭐든지 set -u 처리를 한다고 좋은 것만은 아니므로 주의해야 합니다.

 

 

 

참고서적 : 유닉스 리눅스 셸 스크립트 예제 사전

반응형

댓글