Com o seguinte script shell, por que estou recebendo erros
syntax error near unexpected token `else'
Shell Script
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
Respostas:
Você deve encerrar a condição
if
como esta:ou assim:
Nota: você também precisa colocar espaços
[
antes e depois]
.A razão para a
;
quebra de linha ou é que a parte da condição daif
instrução é apenas um comando. Qualquer comando de qualquer comprimento para ser preciso. O shell executa esse comando, examina o status de saída do comando e decide se deve executar athen
parte ou aelse
parte.Como o comando pode ter qualquer comprimento, é necessário haver um marcador para marcar o final da parte da condição. Essa é a
;
ou a nova linha, seguida porthen
.A razão para os espaços depois
[
é porque[
é um comando. Geralmente um builtin do shell. O shell executa o comando[
com o restante como parâmetros, incluindo o]
último parâmetro como obrigatório. Se você não colocar um espaço após[
o shell, ele tentará executar[whatever
como comando e falhará.A razão do espaço antes do
]
é semelhante. Porque, caso contrário, não será reconhecido como um parâmetro próprio.fonte
test.sh: line 6: [: missing
if
é sintaxe, não é um comando comum. É uma palavra reservada. Ao contrário de muitas outras linguagens de programação, o shell não reconhece palavras reservadas em todos os lugares, apenas quando elas são a primeira palavra de um comando (com algumas sutilezas).if
é sintaxe. Eu estava tentando comunicar que a parte da condição doif
não é restrita a uma determinada forma pela sintaxe. Eu editei o texto. Espero que esteja mais claro agora.Você pode verificar facilmente seus scripts de shell usando o ShellCheck online (também disponível como uma ferramenta independente).
Nesse caso, ele indicará que a instrução if precisa de espaços, depois
[
e antes]
, e que você precisa de uma;
(ou uma nova linha) antesthen
da mesma linha.Quando você tiver corrigido isso, ele continuará dizendo que
USER_NAME
é usado sem ser inicializado em nada. Isso ocorre porque você também tem umauser_name
variável (o caso importa). O mesmo vale paraPASS
epass
.Ele também diz para você usar
read -r
para pararread
de manipular\
(pode ser importante para senhas, por exemplo), e que você deve citar duas vezes as variáveis ao chamarsqlplus
para impedir que o shell acidentalmente faça globbing e divisão de palavras de nomes de arquivos (novamente isso é importante se a senha, por exemplo, contém caracteres ocultos de arquivos como*
espaços ou espaços).Recuar o código também o tornará mais legível:
Aqui também possibilitei o uso de senhas com caracteres de espaço à esquerda ou à direita, configurando temporariamente
IFS
uma string vazia para a leitura da senharead
.A lógica também foi alterada para resgatar se
$ORACLE_SID
/$sid
éTest
. Isso evita ter a parte operacional principal do script em umaif
ramificação.fonte
if ([ x = x ]) then (echo yes) fi
também funciona.if
declarações com[ ... ]
... :-)Ao escrever,
sh
você gostariaAo escrever
bash
Cuide dos espaços, por favor. Deve haver um espaço entre
[[
e o primeiro operador.fonte