"else"가 빈 "then" 절 다음에 오면 Bash 구문 오류가 발생합니다.

"else"가 빈 "then" 절 다음에 오면 Bash 구문 오류가 발생합니다.

다음 스크립트가 실행되지 않지만 구문 오류가 발생하는 이유는 무엇입니까 else?

LOGS3_DIR=~/logs
if [ -d "$LOGS3_DIR" ]; then
 cd
 cd "$LOGS3_DIR"
 echo "$LOGS3_DIR"
 for filename in `find "." -mtime 1 -type f`
  do
  if lsof "$filename" > /dev/null
  then
    # file is open
  else
    echo "deleting $filename"
    rm "$filename"
  fi
 done
fi

답변1

하나 만들어보고 싶은 것 같군요조치 없음파일이 이미 열려 있으면 :빈 명령인 하나를 추가해야 합니다 bash.

if lsof "$filename" > /dev/null; then
  # file is open
  :
else
  printf 'deleting %s\n' "$filename"
  rm -- "$filename"
fi

이를 사용하지 않으면 :코드 bash가 구문 분석되지 않고 이와 같은 오류가 표시됩니다 bash: syntax error near unexpected token 'else'.

답변2

또 다른 옵션은 논리를 뒤집는 것입니다.

if ! lsof "$filename" >/dev/null;then
    echo "deleting $filename"
    rm "$filename"
fi

답변3

출력에 명령 대체를 사용하지 마십시오find. 여기에서는 다음을 통해 모든 작업을 수행할 수 있습니다 find.

find . -mtime 1 -type f ! -exec lsof -t {} \; -exec rm -f {} \; > /dev/null

일부 find구현( find소스 FreeBSD 및 GNU 포함 find)에서는 .-delete-exec rm...

then오류가 발생하는 이유는 및 사이에 명령이 없고 else일부 쉘(이 구문의 출처인 Bourne 쉘로 시작)에는 최소한 하나의 명령이 필요하기 때문입니다(그리고 주석은 명령이 아닙니다). 이는 완전히 임의적이며 이러한 쉘에서는 이를 수행할 이유가 없습니다. yash그리고 zsh이러한 제한이 없습니다( if false; then else echo x; fi심지어 if false; then else fi잘 작동합니다).

다른 사람들이 말했듯이 :(or for nothing in; do nothing; done)와 같은 noop 명령을 사용하거나 키워드를 사용하여 논리를 뒤집을 수 !있습니다(POSIX 쉘에서는 사용 가능하지만 Bourne 쉘에서는 사용할 수 없음(해당 쉘에서는 for를 사용하는 것이 일반적임 :)). mksh그리고 yash그것은 지원됩니다 if false; then () else echo x; fi(향후 버전에서 변경될 수 있으므로 이에 의존하지 않겠습니다).

또 다른 방법은 다음과 같습니다.

lsof... || {
  cmd1
  cmd2
}

차이점 중 하나는 전체 종료 상태, 즉 실패 lsof시 종료 상태 입니다 lsof.

답변4

긴 이야기 짧게

다른 답변 중 실제로 원래 질문을 해결하는 것은 없습니다. 명령에서 구문 오류가 발생하는 이유는 무엇입니까? 이는 사이에 명령이 누락되어 발생합니다.그 다음에그리고기타.

누락된 명령

원본 코드는 다음과 같습니다.

if lsof "$filename" > /dev/null
then
  # file is open
else
  echo "deleting $filename"
  rm "$filename"
fi

문제는 당신 사이에 댓글이 있다는 것입니다그 다음에그리고기타, 그러나 주석은 명령으로 간주되지 않습니다. 즉, 문제를 구조적으로 다음과 같이 다시 작성할 수 있습니다.

$ if true; then else echo; fi
bash: syntax error near unexpected token `else'

Bourne 내장으로 구문 수정

실제 명령을 앞에 넣어서 이 문제를 해결할 수 있습니다.기타, 그러나 주석 자체는 작동하지 않습니다. 이것그렇다면섹션은 비워 둘 수 없습니다. 자리 표시자를 원하면 사용할 수 있습니다.내장 콜론. 예를 들어:

$ if true; then :; else echo; fi

그냥 :사이에 부분을 넣어그 다음에그리고기타발생한 구문 오류를 수정합니다.

관련 정보