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 처리를 한다고 좋은 것만은 아니므로 주의해야 합니다.
참고서적 : 유닉스 리눅스 셸 스크립트 예제 사전
'IT 이야기 > Linux 셸 스크립트' 카테고리의 다른 글
[Linux 셸 스크립트] 파일처리 - 023 절대 경로, 상대 경로 관계없이 같은 동작하기 (0) | 2021.03.11 |
---|---|
[Linux 셸 스크립트] 변환처리 - 022 히어 도큐먼트에서 변수 확장하지 않고 그대로 $str처럼 표시하기 (0) | 2021.03.11 |
[Linux 셸 스크립트] 변환처리 - 020 명령어 출력 결과를 파일명에 포함해서 그 파일명을 대상으로 명령어를 실행할 때 보기 쉽게 하기 (0) | 2021.03.05 |
[Linux 셸 스크립트] 변환처리 - 019 언더스코어 등을 포함한 문자열에서 변수를 명확하게 구분하기 (0) | 2021.03.05 |
[Linux 셸 스크립트] 변환처리 - 018 HTML 파일에서 태그 속에 적힌 주석을 추출해서 그대로 실행하기 (0) | 2021.03.05 |
댓글