예상치 못한 토큰 'fi' 근처에 구문 오류가 있습니다.

예상치 못한 토큰 'fi' 근처에 구문 오류가 있습니다.

나는 반드시 대답을 원하는 것은 아니지만 누군가가 나에게 몇 가지 문헌이나 예를 알려줄 수 있다면. 나는 그것을 알아내고 싶다.

스크립트를 실행하면 오류가 발생합니다.

예상치 못한 토큰 근처의 구문 오류fi

if나는 내 if진술에 주석 echo "$NAME"을 달고 /etc/.

변경 작업을 수행하고 #에서 if및 을 제거 fi하고 에 추가 #하면 wc -c "$NAME"위에 나열된 구문 오류가 발생합니다. 그 ;사이에 추가했어요 ]. 저도 then별 고민 없이 다음 줄로 넘어갔습니다.

#!/bin/bash
for NAME in /etc/*
do

     if [ -r "$NAME" -af "$NAME" ] then
          wc -c "$NAME"
     fi
done

답변1

if, then, else, fi, for등과 같은 키워드는 case쉘이 명령 이름을 예상하는 위치에 있어야 합니다. 그렇지 않으면 일반 단어로 처리됩니다. 예를 들어,

echo if

그냥 인쇄하고 if조건부 명령을 시작하지 않습니다.

따라서 라인에서는

if [ -r "$NAME" -af "$NAME" ] then

단어 then는 명령의 인수입니다 [(실행되면 불평할 것입니다). 쉘은 계속해서 을 찾고 명령 위치에서 then를 찾습니다 . 을(를) 아직 찾고 있는 가 fi있으므로 은 예상치 못한 일입니다. 구문 오류가 있습니다.ifthenfi

then키워드로 인식되도록 하기 위해서는 명령어 종결자를 앞에 넣어야 합니다 . 가장 일반적인 명령 종결자는 줄 바꿈이지만 앞에는 then세미콜론(줄 바꿈과 정확히 동일한 의미를 가짐)을 사용하는 것이 일반적입니다.

if [ -r "$NAME" -af "$NAME" ]; then

또는

if [ -r "$NAME" -af "$NAME" ]
then

[이 문제를 해결하면 명령이 이해하지 못하기 때문에 명령에서 또 다른 오류가 발생합니다 -af. 아마도 당신은 의미

if [ -r "$NAME" -a -f "$NAME" ]; then

테스트 명령은 옵션처럼 보이지만 이렇게 묶을 수는 없습니다. 이들은 [명령의 연산자이며 각각 별도의 단어여야 합니다( do []).

그건 그렇고, [ -r "$NAME" -a -f "$NAME" ]작동하지만 다음 중 하나를 쓰는 것이 좋습니다.

[ -r "$NAME" ] && [ -f "$NAME" ]

또는

[[ -r $NAME && -f $NAME ]]

명령이 연산자와 피연산자를 쉽게 구별할 수 없으므로 [ … ]조건문을 단순하게 유지하는 것이 가장 좋습니다 . 연산자처럼 [보이고 $NAME해당 연산자가 유효한 위치에 나타나면 연산자로 해석될 수 있습니다. 이 답변에 표시된 간단한 경우에는 이런 일이 발생하지 않지만 더 복잡한 경우에는 위험할 수 있습니다. 별도의 호출로 이를 작성 [하고 쉘의 논리 연산자를 사용하면 이 문제를 피할 수 있습니다.

두 번째 구문은 [[ … ]]bash(및 ksh 및 zsh, 일반 sh는 아님)에 존재하는 조건부 구성을 사용합니다. 이 구성은 특수 구문이지만 [다른 명령처럼 구문 분석되므로 내부와 같은 것을 사용할 수 있으며 일부 문자열 연산자( , , , ) &&에 대한 인수를 제외하고 변수를 인용할 필요가 없습니다 .===!==~큰따옴표는 언제 필요합니까?자세한 내용은).

답변2

다음과 같이 변경된 내용을 확인하세요.

if [ -r "$NAME"-a -f"$NAME" ];그 다음에
# ^^^^^ ^
     화장실 -c "$NAME"
fi

if 블록에서 모든 명령을 제거하려면 최소한 콜론을 추가해야 합니다.

if [ -r "$NAME" -a -f "$NAME" ]; then
    :
fi

또는 한 줄 버전

if [ -r "$NAME" -a -f "$NAME" ]; then :; fi

답변3

다른 사람들은 이미 지적했지만 공식적인 참고 자료를 찾고 있다면RTM

목록이면; 그런 다음 나열하십시오. [ 엘리프 목록; 그런 다음 나열하십시오. ] ... [ else 목록;] fi

if 목록이 실행됩니다. 종료 상태가 0이면 then 목록이 실행됩니다. 그렇지 않으면 각 elif 목록이 차례로 실행되고 종료 상태가 0이면 해당 thenlist가 실행되고 명령이 완료됩니다. 그렇지 않으면 else 목록이 있으면 실행됩니다. 종료 상태는 마지막으로 실행된 명령의 종료 상태이거나, true로 테스트된 조건이 없으면 0입니다.

당신은;

그리고 구문은list에 설명되어 있습니다.man test

관련 정보