쉘 스크립트 - 예상치 못한 토큰 'else' 근처에 구문 오류가 있습니다.

쉘 스크립트 - 예상치 못한 토큰 'else' 근처에 구문 오류가 있습니다.

다음 쉘 스크립트를 사용하면 왜 오류가 발생합니까?

syntax error near unexpected token `else'

쉘 스크립트

echo "please enter username"
read user_name
echo "please enter password"
read -s pass
echo ${ORACLE_SID}
SID=${ORACLE_SID}
if ["${ORACLE_SID}" != 'Test'] then
sqlplus -s -l $USER_NAME/$PASS@$SID <<EOF
copy from scott/tiger@orcl insert EMP using select * from EMP
exit
EOF
else
echo "Cannot copy"
fi

답변1

다음과 같이 조건 부분(대괄호)을 종료해야 합니다.

세미콜론으로

if [ "${ORACLE_SID}" != 'Test' ]; then
                                ^ semicolon

또는 개행 문자

if [ "${ORACLE_SID}" != 'Test' ]
                                ^ newline
then

[참고: 앞뒤에도 공백을 추가 해야 합니다 ].

[ "${ORACLE_SID}" != 'Test' ]
 ^ space                   ^ space

배경

또는 줄바꿈이 발생한 이유 는 명령문의 조건부 부분이 단지 명령이기 ;때문입니다 . if말 그대로 모든 길이의 명령입니다. 셸은 명령을 실행하고 명령의 종료 상태를 확인한 다음 해당 then부분을 실행할지 아니면 해당 else부분을 실행할지 결정합니다.

명령의 길이에는 제한이 없으므로 조건 부분의 끝을 표시하는 표시가 필요합니다. 즉 ;, 개행 문자 다음에 then.

뒤에 공백이 있는 이유는 명령이기 [때문입니다 . [일반적으로 쉘의 내장 구성요소입니다. 쉘은 마지막 필수 인수를 [포함하여 나머지 인수를 사용하여 명령을 실행합니다. ]쉘 뒤에 공백을 넣지 않으면 명령으로 실행을 [시도 하고 실패합니다.[whatever

앞의 공백이 있는 이유는 ]비슷하다. 그렇지 않으면 자체 매개변수로 인식되지 않기 때문입니다.

답변2

다음 명령을 사용하여 쉘 스크립트를 쉽게 확인할 수 있습니다.주택 검사온라인(독립형 도구로도 사용 가능)

이 경우 if 문에는 [같은 줄에 있는 공백 앞뒤와 공백 앞에 ]하나 ;(또는 개행)가 필요하다는 점을 지적합니다.then

USER_NAME이를 수정하면 아무것도 초기화되지 않고 사용된다는 메시지가 계속 표시됩니다 . 이는 변수 user_name(대소문자 문제)도 있기 때문입니다. PASS및 에도 마찬가지입니다 pass.

또한 손상을 read -r방지하기 위해 사용하라고 지시하고 (예를 들어 비밀번호에 중요할 수 있음) 쉘이 실수로 파일 이름 일치 및 토큰화를 수행하는 것을 방지하기 위해 호출할 때 변수를 큰따옴표로 묶어야 한다고 지시합니다 (예를 들어 다음과 같은 경우에도 중요합니다. 비밀번호에는 파일 와일드카드 문자(예 : 또는 공백)가 포함됩니다.read\sqlplus*

코드를 들여쓰면 더 읽기 쉬워집니다.

#!/bin/bash

read -r -p 'please enter username: ' user_name
IFS= read -rs -p 'please enter password: ' pass

printf 'ORACLE_SID = %s\n' "$ORACLE_SID"
sid=$ORACLE_SID

if [ "$sid" = 'Test' ]; then
    echo 'Cannot copy' >&2
    exit 1
fi

sqlplus -s -l "$user_name/$pass@$sid" <<'SQL_END'
copy from scott/tiger@orcl insert EMP using select * from EMP
exit
SQL_END

IFS여기에서는 비밀번호를 임시로 빈 문자열로 설정하여 비밀번호를 읽었으며, 앞뒤에 공백 문자가 있는 비밀번호를 사용할 수 있도록 허용했습니다 read.

$ORACLE_SID/ $sidyes 인 경우 종료하도록 논리도 변경되었습니다 Test. 이렇게 하면 스크립트의 주요 작업 부분이 if분기에 있는 것을 방지할 수 있습니다.

답변3

sh당신이 원하는 글을 쓸 때

if [ "$ORACLE_SID" != "Test" ]
then
  ...
fi

글을 쓰는 동안bash

if [[ "$ORACLE_SID" != "Test" ]]
then
  ...
fi

공백에 주의하세요. 와 첫 번째 연산자 사이에는 공백이 있어야 합니다 [[.

관련 정보