.png
.txt
다음 파일 형식 중 하나가 디렉터리에 존재하는지 여부를 감지하고 싶습니다 .tar.gz
.
다음 중 두 가지를 테스트할 때 제대로 작동했습니다.
shopt -s nullglob
MYDIR=/some_dir
if [ $MYDIR/*.png] && [ $MYDIR/*.txt]; then
echo "All files present"
else
echo "At least one type is missing"
fi
하지만 다음을 사용하여 세 가지를 모두 테스트하려고 하면
if [ $MYDIR/*.png] && [ $MYDIR/*.txt] && [ $MYDIR/*.tar.gz]; then
...
또는 사용
if [[ $MYDIR/*.png && $MYDIR/*.txt && $MYDIR/*.tar.gz ]]; then
...
글쎄요, 올바른 동작이 발생하지 않습니다(파일 중 하나가 누락된 경우에도 여전히 true를 반환합니다).
여기서 무슨 일이 일어나고 있는 걸까요?
답변1
파일 이름 와일드카드 패턴이 일치하는지 테스트할 수 없습니다(그리고 [ ... ]
모든 테스트에서 마지막 공백 앞에 공백이 누락되어 코드가 작동하지 않습니다).]
[ ... ]
방법은 일치를 수행하고 일치하는 이름의 수를 계산하는 것입니다.
shopt -s nullglob # make globs expand to nothing if they don't match
shopt -s dotglob # also match hidden names
error=false
for ext in png txt tar.gz; do
set -- "$MYDIR"/*."$ext"
if [ "$#" -eq 0 ]; then
printf 'Nothing matches "%s"\n' "$MYDIR/*.$ext" >&2
error=true
break # possibly, unless you want the user to see all patterns that fail
fi
done
if "$error"; then
echo 'Can not continue' >&2
exit 1
fi
더 많은 것을 입력하고 싶거나 기존 위치 인수 목록을 유지하고 싶다면 명명된 배열을 사용할 수 있습니다. set --
행을 names=( "$MYDIR"/*."$ext" )
및 "$#"
로 변경합니다 "${#names[@]}"
. 모든 따옴표가 중요합니다.
답변2
반드시 다음을 사용해야 합니다.
shopt -s nullglob
말 그대로 테스트하기 전에 거짓 긍정을 피하십시오 $MYDIR/*.png
.
하지만 Bash 테스트에서는 이와 같은 와일드카드를 테스트할 수 없으며 배열을 테스트해야 합니다.
txt=( *.txt ) tgz=( *.tar.gz ) png=( *.png )
if [[ ${txt[@]} && ${png[@]} && ${tgz[@]} ]]; then
echo SUCCESS
fi
해킹을 사용하여 와일드카드가 있는지 테스트하는 또 다른 방법은 다음과 같습니다 compgen
.
cd "$workdir"
if (compgen -W *.txt && compgen -W *.png && compgen -W *.tar.gz) &>/dev/null; then
echo 'SUCCESS'
else
echo >&2 'At least one filetype missed'
fi
bash shebang을 추가하는 것을 잊지 마세요:
#!/bin/bash
또는
#!/usr/bin/env bash
[[
[
명령 과 유사하지만 더 강력한 bash 키워드입니다 . 바라보다http://mywiki.wooledge.org/BashFAQ/031그리고http://mywiki.wooledge.org/BashGuide/TestsAndConditionals. POSIX sh에 글을 쓰는 것이 아니라면 추천합니다.[[
사용 예:
[[ ${names[@]} ]] && echo 'SUCCESS'
당신이 하려고 하는 것처럼 발생 횟수를 셀 필요가 없습니다.