제어 구문 예제_05 스크립트를 수정해서 if문 안이 비더라도 에러가 발생하지 않게 하기

 
  • 출처 : 유닉스 리눅스 쉘스크립트 예제사전_한빛미디어

명령어: :(널 명령어)
키워드: if문, 널 명령어, 빈 줄
사용처: 사양 변경 등으로 필요 없어진 처리를 주석 처리해서 if문 내용이 비었더라도 에러가 발생하지 않게 하고 싶을 때


실행예제

$ ./if-null.sh
$  <------------ 아무것도 하지 않고 정상 종료

스크립트

#!/bin/sh

# 데이터 파일 정의
datafile="/home/user1/myapp/sample.dat"  #--------- 1

# 데이터 파일 존재 확인
if [ -f "$datafile" ]; then  #--------------------- 2
  # 용도 변경으로 필요 없으므로 주석 처리
  # ./myapp "$datafile"

  # 빈 if문은 작성할 수 없으므로 :(널 명령어) 추가
  :
else
  echo "데이터 파일이 존재하지 않습니다: $datafile" >&2
  exit 1
fi

   

해설

이 스크립트는 셸 변수 datafile로 지정한 데이터 파일 존재를 확인해서 파일이 있으면 현재 디렉터리에서 myapp이라는 프로그램을 실행합니다. 그런데 사양이 변경되어 myapp을 실행하지 않아도 되어서 주석 처리한 결과, if문 안이 비어 에러가 발생할 때 이를 해결한다고 가정합니다.

셸 스크립트는 if문 내용이 없으면 에러가 발생합니다. 예를 들어 다음 소스는 lock.tmp라는 잠금 파일이 있으면 아무것도 하지 않고, 없다면 파일을 touch 명령어로 작성하는 스크립트를 만듧니다.

  • 파일1 lock.tmp가 없으면 만드는 스크립트

    #!/bin/sh
    
    if [ -f lock.tmp ]; then
        # 아무것도 하지 않음
    else
        # 잠금 파일 작성
        touch lock.tmp
    fi
    

하지만 실행하면 다음처럼 에러가 발생합니다. 이것은 if문 내용이 비었기 때문입니다.

  • 에러 발생

    $ ./if.sh
    ./if.sh: line 5: syntax error near unexpected token 'else'
    ./if.sh: line 5: 'else'
    

C 언어 등 일반적인 프로그래밍 언어라면 if문 내용이 비어도 문제가 없습니다. 하지만 셸 스크립트에서는 if문이 채워져 있어야 에러가 발생하지 않습니다.

이것은 셸 스크립트 작성 초보자가 자주하는 실수입니다. 특히, 지금까지 동작하던 스크립트가 요구 사양이 변해서 특정 처리가 필요 없어졌을 때, 스크립트를 주석 처리해서 if문 내부에 실행할 명령어가 없어지면 갑자기 에러가 발생하므로 주의해야합니다.

예제에서는 if문 내부를 실행할 필요가 없어졌다고 가정합니다. 우선 1에서 확인할 데이터 파일을 정의하고, 셸 변수 datafile에 파일 경로를 대입합니다.

2에서 대상 데이터 파일 존재를 확인합니다. -f는 대상이 일반 파일인지 확인하는 연산자입니다.

3은 과거에 외부 명령어 myapp을 실행하던 부분입니다. 지금은 필요 없어져서 주석처리했습니다.즉, if문이 이전에는 이랬습니다.

if [ -f "$datafile" ]; then
    ./myapp "$datafile"
else
	echo "데이터 파일이 존재하지 않습니다: $datafile" >&2
    exit 1
fi

여기서 ./myapp를 주석 처리하면 if문 내부가 비어서 스크립트에서 에러가 발생합니다. 따라서 “아무것도 하지 않는 명령어”가 필요합니다. 이런 용도로 셸 내장 명령어 :(널 명령어)가 있습니다.

널 명령어는 실행해도 아무것도 출력하지 않습니다. 실행하면 반드시 성공해서 종료 스테이터스를 0으로 돌려줍니다. 널 명령어는 이 기능을 사용해서 파일 초기화를 하기도 합니다.

4에서 if문 안에 널 명령어를 넣습니다. 널 명령어는 아무것도 하지 않으므로 if문 내부가 비어서 발생하는 에러를 방지할 수 있습니다. 이렇게 해서 실제로는 빈 if문을 작성할 수 있습니다. 특별할 것 없는 내용이지만 실제 환경에서 종종 발생하는 문제이니 알아두면 유용할 것입니다.

   

주의사항

  • FreeBSD의 sh는 if문이 비어도 에러가 발생하지 않습니다. 하지만 이식성을 생각하면 이 예제처럼 널 명령어를 사용하는 것이 좋습니다.