Linux Shell Script 비교와 루프문 - swkim0128/PARA GitHub Wiki
조건문(if..else..fi)
$ if true; then
> echo true
> else
> echo false
> fi
true
$ if true; then echo true; else echo false; fi
true
# style1
$ if COMMANDS
$ then OTHER COMMANDS
$ fi
# style2
$ if COMMANDS
$ then
$ OTHER COMMANDS
$ fi
# style3
$ if COMMANDS; then
$ OTHER COMMANDS
$ fi
[..]vs..
$ tom="Tom hanks"
$ deniro="Robert Deniro"
$ [ $tom > $deniro ]
-bash: $deniro: ambiguous redirect
# [..] 안에서는 >< 문자가 리다이렉트로 해석된다.
$ [[ $tom > $deniro ]]
$ echo $?
0
$ [ $tom = $deniro ]
-bash: [: too many arguments
$ [ "$tom" = "$deniro" ]
$ [ "Tom hanks" = "Robert Deniro" ]
$ [[ $tom = $deniro ]]; echo $?
1
인용부호 사용시 주의사항
$ VAR=; if [ $VAR = "" ]; then echo true; else echo false; fi
-bash: [: =: unary operator expected
false
$ VAR=; if [ "$VAR" = "" ]; then echo true; else echo false; fi
true
$ VAR=; if [[ $VAR = "" ]]; then echo true; else echo false; fi
true
비교 메타 문자열
# hello.txt.bak 파일이 없을 경우에 `cp` 명령어 실행
$ if [ ! -f "hello.txt.bak"" ]; then
> cp "hello.txt" "hello.txt.bak"
> fi
$ if (( $? )); then
> echo 'Please run using "bash" or "sh", but not "." or "source"' > &2
> exit 1
> fi
# 어던 경로에 파일 여부가 있는 지 확인함.
$ if [[ $(ls -A) ]]; then
> echo "there are files"
> else
> echo "no files found"
> fi
비교 메타 문자열
이름 | Description |
---|---|
-e FILE | 파일이 있는 경우 True입니다. |
-f FILE | 파일이 일반 파일인 경우 True입니다. |
-d FILE | 파일이 디렉터리인 경우 True입니다. |
-h FILE | 파일이 심볼 링크인 경우 True입니다. |
-p PIPE | 파이프가 있는 경우 True입니다. |
-r FILE | 사용자가 파일을 읽을 수 있는 경우 True입니다. |
-s FILE | 파일이 존재하며 비어 있지 않은 경우 True입니다. |
-t FD | 터미널에서 FD가 열려 있는 경우 True입니다. |
-w FILE | 사용자가 파일을 쓸 수 있는 경우 True입니다. |
-x FILE | 파일이 실행 가능한 경우 True입니다. |
-O FILE | 파일이 사용자가 효과적으로 소유하는 경우 True입니다. |
-G FILE | 파일이 그룹에 의해 효과적으로 소유되는 경우 True입니다. |
FILE -nt FILE | 첫 번째 파일이 두 번째 파일보다 최신이면 True입니다. |
FILE -ot FILE | 첫 번째 파일이 두 번째 파일보다 오래된 경우 True입니다. |
-z STRING | 문자열이 비어 있으면 True입니다.(길이가 0임) |
-n STRING | 문자열이 비어 있지 않은 경우 True입니다.(길이 0이 아님) |
STRING = STRING | 첫 번째 문자열이 두 번째 문자열과 동일한 경우 True입니다. |
STRING != STRING | 첫 번째 문자열이 두 번째 문자열과 동일하지 않은 경우 True입니다. |
STRING STRING | 첫 번째 문자열이 두 번째 문자열보다 먼저 정렬되는 경우 True입니다. |
STRING STRING 2 | 첫 번째 문자열이 두 번째 문자열 뒤에 정렬되는 경우 True입니다. |
EXPR -a EXPR | 두 식이 모두 참이면 참입니다. (logical AND) |
EXPR -o EXPR | 두 식 중 하나가 참이면 참입니다. (logical OR) |
! EXPR | 표현식의 결과를 반전합니다. (logical NOT) |
INT -eq INT | 두 정수가 동일한 경우 True입니다. |
INT -ne INT | 정수가 동일하지 않은 경우 True입니다. |
INT -lt INT | 첫 번째 정수가 두 번째 정수보다 작은 경우 True입니다. |
INT -gt INT | 첫 번째 정수가 두 번째 정수보다 큰 경우 True입니다. |
INT -le INT | 첫 번째 정수가 두 번째 정수보다 작거나 같으면 True입니다. |
INT -ge INT | 첫 번째 정수가 두 번째 정수보다 크거나 같은 경우 True입니다. |
이름 | Description |
---|---|
STRING = (or ==) PATTERN |
[ 과 같은 문자열 비교는 아니지만 패턴 일치가 수행됩니다. 문자열이 글로브 패턴과 일치하는 경우 True입니다. |
STRING != PATTERN |
[ 과 같은 문자열 비교는 아니지만 패턴 일치가 수행됩니다. 문자열이 글로브 패턴과 일치하지 않는 경우 True입니다. |
STRING =~ REGEX | 문자열이 regex 패턴과 일치하는 경우 True입니다. |
( EXPR ) | 괄호를 사용하여 평가 우선 순위를 변경할 수 있습니다. |
EXPR && EXPR | 테스트의 -a 연산자와 매우 유사하지만 첫 번째 표현식이 이미 거짓으로 판명되면 두 번째 표현식을 평가하지 않습니다. |
EXPR EXPR | 테스트의 -o 연산자와 매우 유사하지만 첫 번째 표현식이 이미 사실인 경우 두 번째 표현식을 평가하지 않습니다. |
case
$ read -p "Enter any string: "
Enter any string: abc
$ case $REPLY in
> +([[:digit:]]) ) echo "digits";;
> *) echo "not digits";;
> esac
not digits
getopts
# 사용자에게 전달인자를 전달받아 사용하는 옵션
select
$ movies=("Avengers" "Matrix" "Titanic")
$ PS3="Please select your favorite movie: "
$ select movie in ${movies[@]}
> do
> echo "$movie selected"
> done
$ movies=("Avengers" "Matrix" "Titanic", "None")
$ PS3="Please select your favorite movie: "
$ select movie in ${movies[@]}
> do
> case $movie in
> "None") echo "My favorite movie is not on the list. quit"; break;;
> *) echo "$movie selected";;
> esac
> done
while 루프
$ while true; do
> echo "hello world"
> sleep 1
> done
$ while true; do
> echo -n -e "\a";
> sleep 1;
> done
$ count=10
$ for no in `eval echo {0..$count}`; do
> echo $no
> done
for..in 루프
$ classroom=(desk pen note chair book)
$ echo ${ classroot[@] }
desk pen note chair book
$ for i in ${ !classroom[@]}; do
# ${!classroom[@}}에서 !: 배열의 인덱스 참조 배열의 요소를 가져오는 것이 아니고 인덱스 값을 얻어오는 방법
> if ["${classroom[$i]}" = 'pen']; then
> classroom[$i]=''
> fi
> done
for((;;)) 루프
$ mystr="Hello world"
$ for(( i=0; i<${\#mystr}; i++)); do
> c="${mystr:$i:1}"
> echo "$c"
> done
루프문과 glob
$ for file in $(ls *.mp3); do
> rm "$file"
error
# 공백 문자에 의해 단어 하나씩 인식되어 삭제됨.
$ for file in "$(ls *.mp3)"; do
> rm "$file";
> done
error
# 인용부호에 의해 mp3 파일들이 각각의 파일로 인식되는 것이 아닌 전체 문장인 하나의 파일로 인식
$ for file in *.mp3
> do rm "%file"
> done
success
# 쉘 스크립트에서 인용부호를 사용해야 할 때와 사용하지 않아야 할 때를 구분할 줄 아는 것이
# 매우 중요합니다.
명령어(date)
$ date +"%Y-%m-%d"
$ date +"%Y/%m/%d"
$ date +"%Y-%m-%d %r"
$ date +"%Y-%m-%d %H:%M"
명령어(seq)
$ seq 0 2 10