본문 바로가기

별걸다하는 IT/리눅스 유닉스

[리눅스 / 유닉스 / 셸 스크립트] 조건문과 함께 쓰이는 test 명령어 사용법 및 활용 예시

반응형

[리눅스 / 유닉스 / 셸 스크립트 프로그래밍 ] 완전 정복 목차

안녕하세요~! 오늘은 오랜만에 리눅스유닉스 포스팅으로 찾아왔어요 ㅎㅎ

오늘은 test 명령어에 대해서 공부해봅시다.

 

test는 조건문과 둘이 커플처럼 사용되는 명령어 이므로 조건문에 대해서 알고 보시는 것이 좋아요 ㅎㅎ

 

[리눅스 / 유닉스 / 셸 스크립트 ] IF문 조건문 - 셸 프로그래밍 기초

[ Linux / Unix / shell scripting 링크 모음 ] 안녕하세요~! 오늘은 프로그래밍하면 가장 먼저 배우는 조건문에 대해서 공부해볼게요 ㅎㅎ 처음에 Shell scripting에서 조건문을 배우면 쫌 헷갈려요. 왜냐면 C언..

jhnyang.tistory.com

여기서도 하단에 test 명령어에 대해서 예고를 했었어요~ ㅎㅎ

test 명령어의 중요성 필요성

명령어 실행 기준이 아닌 결과를 토대로 비교하게 도와주는 test 명령어!

 

if문만 사용했을 경우에는 true와 false 기준이 '명령어가 실행되었는가!'가 입니다.

한 예로 파일이 비어있으면 false 로직을, 파일이 비어있는 파일이 아닌 정보가 담긴 파일이라면 ture 로직을 타게 하고 싶을 때가 있어도 if문 자체는 그걸 수행하지 못해요!!

왜냐면 이걸 판별하는 명령의 결과가 true던 false이던 if문은 관여하지 않고, '명령어가 실행이 되었는지 안되었는지'만 가지고 판별하기 때문이예요.ㅎㅎ 파일이 비어있어도 어쨌던 이를 확인하는 명령어가 작동이 되었으니 true를 타는거죠!

 

하지만 우리가 일반적으로 생각하는 조건문은 이런게 아니죠?!!

이런 것들을 가능하게 해주는 명령어가 test입니다.

참고로 프로그래밍에서 if문이 거의 필수적으로 사용되듯이, 쉘 스크립팅에서 if와 test는 필수적으로 사용되는 명령어이니 꼭 익혀두기!

test 문법 SYNTAX

1. test EXPRESSION
2. [ EXPRESSION ]

대괄호는 test명령어를 의미하도록 정의되어 있어요 ㅎㅎ

즉 1번 표현과 2번 표현은 완전 동일!!

 

★ 조심해야할 것은 대괄호 문법으로 test 명령어를 사용할 때에는 꼭 사이사이에 띄어쓰기를 해줘야 합니다.  

test string1=string2 //WRONG 
test stirng1 = string2 //OK 
[string1 = string2] //WRONG 
[ string1=string2 ] //WRONG 
[ string1 = string2 ] //OK 
# 참고로 test 조건식 내부에 =은 왼쪽 문자열과 오른쪽 문자열이 동일한지 비교해준답니다.

왜 이렇게 띄어쓰기에 예민할까요??

-> 사실 간단해요 ㅎㅎ 일단 인자로 받기 때문입니다.

test는 '['로 정의되어 있는데 ']'가 나올때까지 스페이스를 기준으로 인자로 받아서 처리합니다.

즉 '['또한 이미 정의된 test 명령이예요 ㅎㅎ 명령어를 수행하려면 띄어쓰기가 필수잖아요? 그래서 [ 다음에 무조건 띄어쓰기가 와야합니다.

'[string ' 이렇게 띄어쓰기 없이 붙이면 명령어 [를 인식하지 못해요 ㅎㅎ 그래서 '[ string'처럼 [다음에 띄어쓰기를 넣어준 후 조건식이 이어져야 합니다.

[ string1=string2 ] 이렇게 되면 test명령어는 'string1=string2'를 하나의 인자로 착각하게 됩니다. 실질적으로는 첫 번째 인자로 string1을 받고 두번째 인자로 '='을 받고 세 번째 인자로 string2를 받아서 처리해야 하는데 ~~~ [ string ] 이렇게 안에 string 변수 하나 있는거랑 다를바가 없어요 ㅎㅎ 

결론: 띄어쓰기를 사이사이 해주자

test 확인법

1. echo $?

여기 보이는 '$?'는 최근 명령어의 종료상태를 담고 있는 특수변수예요 ㅎㅎ

echo가 보여주는 명령어이니까 'echo $?' 하면 최근 명령어의 종료상태를 보여달라는거죠.

이를 이용해서 test 명령어 수행 결과가 무엇을 반환했는지 확인해볼 수 있습니다.

거짓일때 1을 반환하네요? 보통은 1을 true라고 생각하는데 반대예요 ㅎㅎ

(정확히는 정상적으로 명령어가수행되었을 때 $?는 0을 반환합니다. test가 조건결과가 참이면 정상명령으로 판단해요)

 

다른 프로그래밍 언어에선 참일 때 1을 반환하지만 test 명령어는 조건 결과가 참일 때 0을 반환한다는 차이점을 이렇게 확인할 수 있지요 ㅎ

2. && , ||

test right = left && echo YES || echo NO

프로그래밍 언어에서 사용하는 삼항연산자 문법과 비스무리하게 보이네요 ㅎㅎ

조건식이 참이면, (즉 종료상태가 0이면) && 뒤에 있는 로직을 수행하고, 거짓이면 ||뒤에 있는 로직을 수행합니다. 

사진에서 test와 '[ ]'는 같은 상호교환되는 동일한 명령어라는 것을 다시 한 번 확인할 수 있어요 

3. if명령어와 함께~

if문과 함께 자주 사용되죠 ~

if [ string1 = string2 ] 
then echo "same" 
else echo "not same!" 
fi

실제 수행 예시

명령어를 한 번에 사용하고 싶을 때에는 ';'를 이용해서 그 라인의 명령이 끝났음을 명시해줘야 합니다 ㅎㅎ

test 종류에 따른 다양한 사용법 및 명령어 예시

test에는 우리가 앞에서 예시로 계속 들었던 문자열 비교 '='외에도 다양한 사용 방법이 있어요 ㅎㅎ

문자열 비교

말 그대로 문자열을 비교하는데 사용할 수 있는 방법들~

 

종류

설명

[ string ] 

string이 빈 문자열이 아니라면 참

[ string1 = string2 ] 

두 문자열이 같다면 참

[ string1 != string2 ]

두 문자열이 다르면 참

[ -n string ]

문자열이 null(빈 문자열)이 아니라면 참

[ -z string ]

문자열이 null(빈 문자열)이면 참 (zero)

사용 예시

▶ != , 변수값 비교

if [ ${OPTION} != "NOZIP" ]; then 
    zip_files ${CURDATE} //함수

 

요건, 만약 옵션에 NOZIP이라고 되어있지 않으면, 파일 압축 함수를 오늘날짜로 실행한다 라는 의미를 담아 작성해보었아요~ ㅎㅎ

▶ -z

1. if [ -z $DIR_NAME ]; ~~~ 
2. if [ x$DIR_NAME = x ]; ~~

DIR_NAME변수가 비어있는 문자열인지 확인하는 두 가지 방법~ 

▶ [ string ] 명령어와 함께 사용

if [ "$(ls -A *backup*)" ]; then echo "backup file exists"; fi

현재 폴더에 backup이라는 문자열이 포함된 파일이나 디렉터리가 있으면 ~

큰따옴표는 결과가 하나가 아니라 리스트로 나올 수 있으므로 붙여줬어요

이렇게 명령어의 실행 결과를 반환함으로써 존재하는지 존재하지 않는지 여부에 따라 로직을 따르게 할 수도 있습니다. 이런식으로 명령어의 결과값 여부로 판단하는거 넘나 많이 쓰는 것..

 

산술 비교

종류

설명

[ expr1 -eq expr2 ] 

두 표현식 값이 같다면 참 (equal)

[ expr1 -ne expr2 ]

두 표현식 값이 같지 않다면 참 (not equal)

[ expr1 -gt expr2 ]

expr1 > expr2 이면 참 (greater than)

[ expr1 -ge expr2 ]

expr1 >= expr2 이면 참 (greater equal)

[ expr1 -lt expr2 ]

expr1 < expr2 이면 참 (less than)

[ expr1 -le expr2 ]

expr1 <= expr2 이면 참 (less eqaul)

[ ! expr ]

expr이 참이면 거짓, 거짓이면 참

[ expr1 -a expr2 ]

expr1 AND expr2의 결과, 즉 둘 다 참이면 참

[ expr1 -o expr2 ]

expr1 OR expr2의 결과, 즉 둘 중 하나만 참이면 참

사용 예시

▶-gt , 직접 비교

if test 100 -gt 99 
then echo "100 > 99" 
else echo "100 < 99" 
fi

이렇게 숫자로 직접 비교할 수도 있지만~~ 

▶-eq , 변수 값 비교

if [ $return_val -eq 1 ]; 
   then echo "return value is 1"; else echo "return value is not 1"; 
fi

이렇게 변수에 담긴 값을 비교하는 데 더 많이 사용되죠 ㅎㅎ

▶-lt, 산술연산 명령어와 써보기

if [ `expr $num1 + $num2 ` -lt `expr $num3 + $num4 ` ]; then 
echo "num1+num2 < num3+num4"; 
else echo "num1+num2 > num3+num4"; 
fi

아무래도 산술연산이다보니까 expr 명령어처럼 산술 연산 명령어와 자주 쓰입니다.

파일 조건

종류

설명

[ -b FILE ] 

FILE이 블록 디바이스면 참

[ -c FILE ] 

FILE이 문자 디바이스면 참

[ -d FILE ] 

FILE이 디렉터리이면 참

[ -e FILE ] 

FILE이 존재하면 참

[ -f FILE ] 

FILE이 존재하고 정규 파일이면 참

(호환성 문제로 -e보다 -f가 주로 사용)

[ -g FILE ] 

FILE에 SGID가 있으면 참

[ -k FILE ] 

FILE에 Sticky bit가 있으면 참

[ -L FILE ] 

FILE이 심볼릭 링크이면 참

[ -p FILE ] 

FILE이 Named pipe이면 참

[ -r FILE ] 

현재 사용자가 읽을 수 있는 파일이면 참

[ -s FILE ]

파일이 비어있지 않으면 참

[ -S FILE ]

소켓 디바이스이면 참

[ -t FD ]

FD(File Descriptor)가 열려진 터미널이면 참

[ -u FILE ]

FILE에 SUID가 있으면 참

[ -w FILE ]

현재 사용자가 쓸 수 있는 파일(writable file)이면 참

[ -x FILE ]

현재 사용자가 실행할 수 있는 파일 (Excute file)이면 참

[ -O FILE ]

FILE의 소유자가 현재 사용자이면 참

[ -G FILE ]

FILE의 그룹이 현재 사용자의 그룹과 같으면 참

[ FILE1 -nt FILE2 ]

FILE1이 FILE2보다 새로운 파일(최근 파일)이면 참

[ FILE1 -ot FILE2 ]

FILE1이 FILE2보다 오래된 파일이면 참

[ FILE1 -et FILE2 ]

FILE1이 FILE2의 하드 링크, 즉 I-node 값이 같으면 참

사용 예시

▶-d, 함수로 사용해보기 

make_dir() { 
   if ! test -d $1 
   then 
       echo "no directory -> make new one" 
       mkdir -p $1 
   fi
} 
make_dir /ella/backup

함수 인자로 파일명을 넣어줬을 때, 해당 파일명을 가진 디렉터리가 없으면 디렉터리를 새로 만드는 함수입니다.

▶-s, !연산자

if test ! -s "$fname" 
then 
   echo $fname does not exist or is empty 
fi

-s옵션은 파일이 비어있지 않으면 참이라고 했는데 !가 붙어서 부정이 되어 파일이 비어있으면 참이 됩니다.

근데 여기서 파일이 비어있다는 의미는 말그대로 빈 파일일 수도 있지만 존재하지 않을 경우에도 빈파일로 봐서 참으로

반환한다는거~

 

그냥 test문법만 알려주는 것보다는 이런저런 코드를 많이 보는게 좀 더 도움이 될 것 같아서 명령어를 다양하게 써보려고 했어요 ㅎㅎ

 

오늘은 여기까지~~!!

다음에 또 봐요 여러분들 ~!

공감과 댓글, 광고보답은 더 질좋은 포스팅을 작성하는데 큰 응원이됩니다 :)

반응형