- 출처 : 유닉스 리눅스 쉘스크립트 예제사전_한빛미디어
명령어: test, [
키워드: 파일 속성, 상태 확인, 파일 테스트, 권한
사용처: 스크립트 초기 설정 등에서 특정 파일의 존재 확인이나 권한 확인을 하고 싶을 때
실행예제
$ ./test.sh
start.
스크립트
#!/bin/sh
start_command="./start.sh"
if [ -x "$start_command" ]; then # ------------------ 1(if문 전체)
$start_command
else
echo "ERROR: -x $start_command failed." >&2
exit 1
fi
해설
이 스크립트는 현재 디렉터리에 있는 start.sh를 실행하는 간단한 스크립트입니다. start.sh를 실행할 수 있는지를 스크립트 내부에서 미리 확인해서 판별합니다. 여기서 start.sh는 무언가를 처리하는 스크립트로 가정했는데 이 예제는 “start.sh”를 출력합니다.
이 예제에서는 스크립트 안에서 다른 명령어를 실행할 수 있는지를 test 명령어에 파일실행 권한을 확인하는 -x 연산자를 붙여 확인합니다. 파일 상태를 조사하는 연산자는 많은데 자주 사용하는 것만 다음 표에 모아뒀습니다. 예를 들어 스크립트 기동 초기에 -w로 로그 디렉터리에 쓸 수 있는지 조사하거나 -r로 설정 파일을 읽을 수 있는지 확인하는 용도로 자주 사용합니다.
-
test 명령어 주요 연산자
연산자 설명 -d 파일이 존재하고 디렉터리라면 참 -e 파일이 존재하면 참 -b 파일이 존재하고 블록 스페셜 파일이면 참 -c 파일이 존재하고 캐릭터 스페셜 파일이면 참 -f 파일이 존재하고 일반 파일(regular file)이면 참 -L 파일이 존재하고 심볼링 링크라면 참 -r 파일이 존재하고 읽기 가능하면 참 -w 파일이 존재하고 쓰기 가능하면 참 -x 파일이 존재하고 실행 가능하면 참 -s 파일이 존재하고 크기가 0보다 크면 참 -O 파일이 존재하고 실행 중인 셸의 실효 사용자 ID가 소유자면 참 -S 파일이 존재하고 소켓 파일이면 참 더 많은 연산자가 있으므로 man test로 확인해보기 바랍니다.
지금까지 test 명령어라고 서술했는데 실제로는 1
에서 if문에 있는 [
는 제어 구조를 나타내는 괄호가 아니라 test 명령어와 같은 명령어입니다. 예를 들어 다음처럼 명령어 이름을 해설하는 type 명령어로 조사해보면 [
명령어가 셸 내장 명령어라는 걸 알 수 있습니다.
-
[
가 명령어라는 걸 확인하기$ type [ [ is a shell builtin
하지만
[
명령어가 test 명령어와 다른 것은[
명령어는 마지막 인수로 닫는 괄호]
가 필요하다 라는 점입니다. 따라서 if문 조건식에서 사용하면 조건 전체가 괄호로 둘러 쌓여서 보기 좋으므로 자주 쓰입니다. 예제1
은 아래처럼 작성할 수 있습니다.if test -x "$start_command"; then
test 명령어는 조건 판단을 해서 그 결과가 참이면 종료 스테이터스로 0을 둘려줍니다.
if 문에서는 이 종료 스테이터스에 따라 참거짓 값을 판별합니다.일반적으로 if문 조건식으로 [ ]를 많이 사용하지만, test 명령어는 물론이고 그 외에도 종료 스테이터스를 판단하는 명령어는 뭐든 쓸 수 있습니다. 예를 들어 다음은 if문 조건식에서는 grep 명령어를 그대로 사용합니다. 여기서는 sample.txt 파일에 문자열 “bin”이 포함되었는지 확인합니다.
#!/bin/sh if grep -q "bin" sample.txt ; then echo "sample.txt has string [bin]" fi
grep 명령어는 일치한 문자열이 있을 때는 종료 스테이터스 0, 일치하지 않으면 1을 돌려주므로 if 조건식으로 사용할 수 있습니다.
주의사항
-
‘만약 실행 가능한 파일이면 실행한다’ 라는 단순한 조건을 간단하게 작성하면 다음과 같습니다.
test -x start.sh && ./start.sh
&&
로 명령어를 연결하면 앞 명령어가 성공하면(즉 종료 스테이터스가 0이면) 다음 명령어를 실행하도록 지정할 수 있습니다. 여기서 test -x 명령어가 성공하면 실행 가능하다는 의미이므로 이어서 다음 명령어를 실행하는 것입니다. -
이 예제에서는 셸 변수 start_command로 지정한 파일이 디렉터리인지 확인하지 않았습니다. 따라서 드문 경우지만 [start.sh]라는 이름의 디렉터리가 있으면 에러가 발생합니다. 잘 처리하려면
1
의 if문을 아래와 같이 -f로 일반 파일인지 확인한 다음 실행해야 합니다. 이때 -a는 test 명령어로 AND를 의미하는 연산자입니다.if [ -f "$start_command" -a -x "$start_command" ]; then