shell 에서 test는 파일 형식 확인 및 값 비교를 위해 사용



7.1. if에 대한 소개

7.1.1. 일반적인

명령의 성공 또는 실패에 따라 쉘 스크립트에서 수행할 다른 작업 과정을 지정해야 하는 경우가 있습니다. if 구성을 사용하면 이러한 조건을 지정할 수 있습니다.

if 명령 의 가장 간결한 구문은 다음과 같습니다.

if TEST-COMMANDS; then CONSEQUENT-COMMANDS; fi

 

 

TEST-COMMAND 목록 이 실행되고 반환 상태가 0이면 CONSEQUENT-COMMANDS 목록이 실행됩니다. 반환 상태는 마지막으로 실행된 명령의 종료 상태이거나 true로 테스트된 조건이 없으면 0입니다.

TEST-COMMAND 는 숫자 또는 문자열 비교 테스트를 포함하지만 성공하면 0 상태를 반환하고 실패하면 다른 상태를 반환합니다. 

단항 표현식은 종종 파일의 상태를 검사하는 데 사용됩니다. stdin , stdout 및 stderr 및 각각의 파일 설명자를 테스트에 사용할 수도 있습니다.

7.1.1.1. if와 함께 사용되는 표현식

아래 표에는 TEST-COMMAND 명령은 조건식의 테스트를 나타내기 위해 대괄호( [] ) 사이에 넣습니다.

표 7-1. 기본 표현식

주요한의미
[ - 파일 ] FILE 이 있으면 참 입니다.
[ -b 파일 ] FILE 이 존재하고 블록 특수 파일 이면 참 입니다.
[ -c 파일 ] FILE 이 존재하고 문자 특수 파일 이면 참 입니다.
[ -d 파일 ] FILE 이 존재하고 디렉토리 이면 참 입니다.
[ -e 파일 ] FILE 이 있으면 참 입니다.
[ -f 파일 ] FILE 이 존재하고 일반 파일 이면 참 입니다.
[ -g 파일 ] FILE 이 존재하고 SGID 비트가 설정되어 있으면 참 입니다.
[ -h 파일 ] FILE 이 존재하고 심볼릭 링크 이면 참 입니다.
[ -k 파일 ] FILE 이 존재하고 고정 비트가 설정되어 있으면 참 입니다.
[ -p 파일 ] FILE 이 존재하고 명명된 파이프(FIFO)인 경우 참 입니다.
[ -r 파일 ] FILE 이 존재하고 읽을 수 있으면 참 입니다.
[ -s 파일 ] FILE 이 존재하고 크기가 0보다 크면 참 입니다.
[ -t FD ] 파일 설명자 FD 가 열려 있고 터미널을 참조하는 경우 참 입니다.
[ -u 파일 ] FILE 이 존재하고 SUID(사용자 ID 설정) 비트가 설정되어 있으면 참 입니다.
[ -w 파일 ] FILE 이 존재하고 쓰기 가능한 경우 참 입니다.
[ -x 파일 ] FILE 이 존재하고 실행 가능한 경우 참 입니다.
[ -O 파일 ] FILE 이 존재하고 유효 사용자 ID가 소유한 경우 참 입니다.
[ -G 파일 ] FILE 이 존재하고 유효 그룹 ID가 소유한 경우 참 입니다.
[ -L 파일 ] FILE 이 존재하고 심볼릭 링크 이면 참 입니다.
[ -N 파일 ] FILE 이 존재하고 마지막으로 읽은 이후 수정 되었으면 참 입니다.
[ -S 파일 ] FILE 이 존재하고 소켓 이면 참 입니다.
[ 파일 1 - 파일 2 ] FILE1 이 FILE2 보다 최근에 변경 되었거나 FILE1 이 있고 FILE2 가 없는 경우 true 입니다.
[ 파일 1 - 파일 2 ] FILE1 이 FILE2 보다 오래된 경우 또는 FILE2 가 있고 FILE1 이 없는 경우 참 입니다.
[ 파일1 -ef 파일 2 ] FILE1 및 FILE2 가 동일한 장치 및 inode 번호를 참조하는 경우 참 입니다.
[ -o 옵션 이름 ] 셸 옵션 "OPTIONNAME" 이 활성화된 경우 True입니다.
[ -z 문자열 ] "STRING" 이 0 이면 길이가 참입니다. space나 tab 만으로 구성된 경우에도 문자열 길이가 0 입니다.
[ -n STRING ] 또는 [ STRING ] "STRING" 의 길이 가 0이 아니면 참 입니다.
[ STRING1 == STRING2 ] 문자열이 같으면 참입니다. 엄격한 POSIX 준수를 위해 " =" 대신 "=" 를 사용할 수 있습니다.
[ STRING1 != STRING2 ] 문자열이 같지 않으면 참입니다.
[ STRING1 < STRING2 ] "STRING1 " 이 현재 로케일에서 사전 순으로 "STRING2" 보다 먼저 정렬 되면 true 입니다.
[ STRING1 > STRING2 ] "STRING1" 이 현재 로케일에서 사전 순으로 " STRING2" 다음에 정렬 되면 참 입니다.
[ ARG1 OP ARG2 ] "OP" 는 -eq , -ne , -lt , -le , -gt 또는 -ge 중 하나입니다 . 이러한 산술 이항 연산자는 각각 "ARG1" 이 "ARG2" 와 같거나 같지 않거나 작거나 같거나 크거나 같으면 true를 반환합니다 . "ARG1" 및 "ARG2" 는 정수입니다.

 

표 7-2. 표현식 결합


[ ! EXPR] EXPR 이 거짓 이면 참 입니다.
[ ( EXPR) ] EXPR 값을 반환합니다 . 이것은 연산자의 일반적인 우선 순위를 무시하는 데 사용할 수 있습니다.
[ EXPR1 -a EXPR2 ] EXPR1 과 EXPR2 가 모두 참이면 참입니다.
[ EXPR1 -o EXPR2 ] EXPR1 또는 EXPR2 가 참 이면 참입니다.

 if 가 fi 로 닫히는 것처럼 여는 대괄호는 조건이 나열된 후에 닫아야 합니다.

7.1.1.2. then 문 다음에 나오는 명령

then 문 다음에 오는 CONSEQUENT-COMMANDS 목록은 fi 를 제외하고 모든 유효한 UNIX 명령, 실행 프로그램, 실행 가능한 셸 스크립트문이 될 수 있습니다 . then 과 fi 는 쉘에서 분리된 문장으로 간주됩니다 . 따라서 명령줄에서 실행될 때 세미콜론으로 구분됩니다.

 

7.1.1.3. 파일 확인 중

첫 번째 예는 파일의 존재하는지를 확인합니다.

$ cat filecheck.sh
#!/bin/bash

echo "This scripts checks the existence of the messages file."
echo "Checking..."
if [ -f /var/log/messages ]
  then
    echo "/var/log/messages exists."
fi
echo
echo "...done."

$ filecheck.sh
This scripts checks the existence of the messages file.
Checking...
/var/log/messages exists.

...done.

 

7.1.2. if의 간단한 응용

7.1.2.1. 종료 상태 테스트

?  변수는 이전에 실행된 명령(가장 최근에 완료된 포그라운드 프로세스)의 종료 상태를 유지합니다.

다음 예는 간단한 테스트를 보여줍니다.

#!/bin/bash
echo '$? : check return value'

if [ $? -eq 0 ]
then 
    echo 'before task is successful!'
fi

## Result
before task is successful!

 

7.1.2.2. 수치 비교

아래 예에서는 숫자 비교를 사용합니다.

#!/bin/bash
num=201

if [ "$num" -gt "150" ]
then 
    echo "you've worked hard enough for today."
fi

## Result 
you've worked hard enough for today

 

7.1.2.3. 문자열 비교

사용자 ID 테스트를 위한 문자열 비교의 예:

if [ "$(whoami)" != 'root' ]; then
        echo "You have no permission to run $0 as non-root user."
        exit 1;
fi

-- Result
You have no permission to run ./script.sh as non-root user.

 

Bash를 사용하면 위의 내용을 다음과 같이 간결하게 쓸 수 있습니다.

[ "$(whoami)" != 'root' ] && ( echo "you are using a non-privileged account"; exit 1 )

 "&&"는 테스트가 true인 경우 수행할 작업을 지정합니다 .  "||" 테스트가 false인 경우 수행할 작업을 지정합니다.

 

비교에 정규 표현식을 사용할 수도 있습니다.

#!/bin/bash

gender="female"

if [[ "$gender" == f* ]]
then 
    echo "Pleasure to meet you.";
fi

## Result
Pleasure to meet you.

 

 

'Shell' 카테고리의 다른 글

쉘 - 문자열 포함 여부  (0) 2022.01.16
쉘 - $#, $*, $@  (0) 2022.01.16
shell - dirname  (0) 2022.01.16
쉘 - dirname  (0) 2022.01.16
[bash 쉘 스크립트] 종료(exit)  (0) 2022.01.15

shell script 에서 때로는 문자열 패턴의 일치 여부를 확인하는 것이 아니라 포함되는지 확인해야 하는 경우가 있습니다.

 

아래 예시를 살펴보겠습니다.

AA="My name is oops"
BB="name"

 

변수 $BB가 $AA에 포함되는지 확인하는 방법에는 여러가지가 있겠지만 아래 두 가지 방법을 소개합니다.

 

#!/bin/bash

AA="My name is oops"
BB="name"

if [[ "$AA" == *"$BB"* ]];then
    echo "1st find it"
fi

if [[ "$AA" =~ "$BB" ]];then
    echo "2nd find it"
fi

 

문자열 패턴을 이용한 ** 방법이 있고, =~ 를 이용하는 방법이 존재합니다.

 

'Shell' 카테고리의 다른 글

shell - test  (0) 2022.01.16
쉘 - $#, $*, $@  (0) 2022.01.16
shell - dirname  (0) 2022.01.16
쉘 - dirname  (0) 2022.01.16
[bash 쉘 스크립트] 종료(exit)  (0) 2022.01.15

shell 에서 사용되는 $#, $*, $@, $# 에 대해 알아본다.

 

$0 : Script를 실행시킬 때 프로그램의 이름이 첫 번째 문자열에 저장
$1, ...$N : argument들이 순서대로 저장
$* : 모든 파라미터들로 구성된 단일 문자열
$@ : 파라미터들을 각각 별도의 구분된 문자로 취급
$# : 위치 매개변수의 갯수가 저장

 

예제 1) $# 

아래와 같은 스크립트 코드가 있다. 파일명은 script1.sh 로 했다.

#!/bin/sh
echo "\$# 예제"
echo " 프로그램명 : $0"
echo " 첫번째 파라미터 : $1"
echo " 첫번째 파라미터 : $2"
echo " 첫번째 파라미터 : $3"
echo "파라미터 갯수 : $#"

이 스크립트를 실행시켜보자.

$ sh script1.sh arg1 arg2 arg3

결과는 아래와 같다. 즉 파라미터가 4개임을 출력한다.

$# 예제
 프로그램명 : script1.sh
 첫번째 파라미터 : arg1
 첫번째 파라미터 : arg2
 첫번째 파라미터 : arg3
파라미터 갯수 : 3

 

예제 2) $@와 $* 차이

아래와 같은 스크립트 코드가 있다. 파일명은 script2.sh 로 했다.

#!/bin/sh
echo "\$@ 예제"
echo "----------"
for param in "$@"
do
    echo $param,
done

echo "\$* 예제"
echo "----------"
for param in "$*"
do
    echo $param,
done

이 스크립트를 실행시켜보자.

$ sh script2.sh A B C

결과는 아래와 같다.

$ sh script2.sh A B C
$@ 예제
----------
A,
B,
C,
$* 예제
----------
A B C,

예제처럼 $@는 N개의 배열처럼 동작하고, $*는 모든 parameter를 한개의 스트링으로 인식한다. 경우에 맞도록 사용하면 되겠다.

'Shell' 카테고리의 다른 글

shell - test  (0) 2022.01.16
쉘 - 문자열 포함 여부  (0) 2022.01.16
shell - dirname  (0) 2022.01.16
쉘 - dirname  (0) 2022.01.16
[bash 쉘 스크립트] 종료(exit)  (0) 2022.01.15

dirname은 기본적으로 리눅스에서 제공하는 명령어로서 dirname [fullPath] 형식으로 사용된다.
fullPath에서 파일이름을 제외한 path 부분을 리턴해주며, 파일이나 디렉토리가 존재하지 않아도 입력된 fullPath 에서 path 형식으로 된 부분을 리턴한다.

예제 1) 파일이 존재하는 경우 dirname

/mnt/d/kafka/kafka/bin$ dirname /mnt/d/kafka/kafka/bin/exist.file
/mnt/d/kafka/kafka/bin

예제 2) 파일이 존재하는 않는 경우 dirname

/mnt/d/kafka/kafka/bin$ dirname /mnt/d/kafka/kafka/bin/non_exist.file
/mnt/d/kafka/kafka/bin

위와 같이 파일의 존재유무와 상관없이 파일이름은 제외한 full path 를 리턴해 준다.

'Shell' 카테고리의 다른 글

shell - test  (0) 2022.01.16
쉘 - 문자열 포함 여부  (0) 2022.01.16
쉘 - $#, $*, $@  (0) 2022.01.16
쉘 - dirname  (0) 2022.01.16
[bash 쉘 스크립트] 종료(exit)  (0) 2022.01.15

dirname은 기본적으로 리눅스에서 제공하는 명령어로서 dirname [fullPath] 형식으로 사용된다.
fullPath에서 파일이름을 제외한 path 부분을 리턴해주며, 파일이나 디렉토리가 존재하지 않아도 입력된 fullPath 에서 path 형식으로 된 부분을 리턴한다.

예제 1) 파일이 존재하는 경우 dirname

/mnt/d/kafka/kafka/bin$ dirname /mnt/d/kafka/kafka/bin/exist.file
/mnt/d/kafka/kafka/bin

예제 2) 파일이 존재하는 않는 경우 dirname

/mnt/d/kafka/kafka/bin$ dirname /mnt/d/kafka/kafka/bin/non_exist.file
/mnt/d/kafka/kafka/bin

위와 같이 파일의 존재유무와 상관없이 파일이름은 제외한 full path 를 리턴해 준다.

'Shell' 카테고리의 다른 글

shell - test  (0) 2022.01.16
쉘 - 문자열 포함 여부  (0) 2022.01.16
쉘 - $#, $*, $@  (0) 2022.01.16
shell - dirname  (0) 2022.01.16
[bash 쉘 스크립트] 종료(exit)  (0) 2022.01.15

개요

 

Bash 쉘에서 프로그램을 종료(exit) 하는 방법과 종료 상태(exit status)를 얻는 방법에 대해 설명드리겠습니다.

종료 상태는 리턴값(return value, return status)이라고 부르기도 하는데 이전에 수행했던 명령어나 프로그램이 종료 될 때 넘겨주는 값을 의미합니다.

 

쉘 스크립트 내에서 exit 명령어가 실행되면 스크립트가 종료되며 부모 프로세스에 종료 상태를 전달할 수 있는데 이 값은 프로그램 내에서 임의로 지정할 수도 있습니다. 

 

일반적으로 명령어의 종료 상태가 0이면 성공(success)이고 이외의 코드는 오류이며 0보다 큰 오류 코드를 반환합니다.

 

 

종료 (exit)

 

exit 명령어는 매개변수로 주어진 값을 리턴합니다. 

#!/bin/bash

echo "hello"
exit 100

 

예를들면 위와 같이 exit 100 이라고 작성하면 스크립트를 종료하면서 100 이라는 값을 리턴하는 것이죠.

이 때 종료 상태로 사용할 수 있는 값의 범위는 0 부터 255 까지입니다. 만일 exit 코드를 256이라고 지정하면 0 이 리턴됩니다. 한바퀴 돌아서 256으로 나눈 나머지 값을 리턴하게 됩니다. 원치 않는 결과가 나올수 있으니 exit 코드를 지정할려면 반드시 0과 255 사이값이 지정해야 합니다.

일반적으로 unix 관행을 잘 따르는 경우 0은 성공, 1 ~ 255 는 오류 코드(error code) 입니다.

 

만일 exit 를 리턴코드 없이 사용하게 되면 exit 가 실행되기 이전에 가장 마지막으로 수행됐던 명령어의 종료 상태를 반환하게 됩니다.

 

 

종료 상태 (exit status)

 

$? 는 가장 최근 명령어의 종료 상태를 나타냅니다. 

위 스크립트가 100을 반환한다고 했는데 정말 그런지 실행 후 종료 상태를 출력해보겠습니다.

 

$ sh test.sh
hello

$ echo $?
100

 

위와 같이 echo $? 명령어에서 100이 출력되는 것을 확인할 수 있습니다.

 

만일 잘못된 명령어를 입력하여 오류가 발생한 경우는 아래와 같이 오류코드가 반환되는 것을 확인할 수 있습니다.

$ bacde
-bash: eeee: command not found
$ echo $?
127

 

아래 스크립트에서는 echo "hello" 가 정상적으로 수행되었기 때문에 0이 반환된 것을 확인할 수 있습니다.

$ echo "hello"
hello
$ echo $?
0

 

출처: https://gracefulprograming.tistory.com/70 [Peter의 우아한 프로그래밍]

'Shell' 카테고리의 다른 글

shell - test  (0) 2022.01.16
쉘 - 문자열 포함 여부  (0) 2022.01.16
쉘 - $#, $*, $@  (0) 2022.01.16
shell - dirname  (0) 2022.01.16
쉘 - dirname  (0) 2022.01.16

+ Recent posts