Erro de sintaxe próximo ao token inesperado `fi`

Erro de sintaxe próximo ao token inesperado `fi`

Não quero necessariamente a resposta, mas se alguém puder me indicar alguma literatura ou exemplos. Eu gostaria de descobrir isso.

Quando executo o script, recebo um erro:

Erro de sintaxe próximo token inesperadofi

Deduzi que meu problema está em minha ifdeclaração, fazendo ifcomentários sobre minhas declarações e adicionando echo "$NAME"quais exibem os nomes no arquivo /etc/.

Quando faço alterações, removo #from ife fiadiciono #to wc -c "$NAME", recebo o erro de sintaxe listado acima. Eu adicionei ;entre ]então. Também mudei thenpara a próxima linha sem resolução.

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

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

Responder1

Palavras-chave como if, then, else, fi, e assim por fordiante caseprecisam estar em um local onde o shell espera um nome de comando. Caso contrário, serão tratadas como palavras comuns. Por exemplo,

echo if

apenas imprime if, não inicia uma instrução condicional.

Assim, na linha

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

a palavra thené um argumento do comando [(do qual ele reclamaria se fosse executado). O shell continua procurando por thene encontra uma fiposição de comando. Como há um ifque ainda está procurando por seu then, fié inesperado, há um erro de sintaxe.

Você precisa colocar um terminador de comando antes thenpara que seja reconhecido como uma palavra-chave. O terminador de comando mais comum é uma quebra de linha, mas antes thené comum usar ponto e vírgula (que tem exatamente o mesmo significado de uma quebra de linha).

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

ou

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

Depois de corrigir isso, você receberá outro erro do comando [porque ele não entende o arquivo -af. Você provavelmente quis dizer

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

Embora os comandos de teste pareçam opções, você não pode agrupá-los dessa forma. Eles são operadores do [comando e cada um precisa ser uma palavra separada (como do [e ]).

A propósito, embora [ -r "$NAME" -a -f "$NAME" ]funcione, recomendo escrever

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

ou

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

É melhor manter [ … ]as condicionais simples porque o [comando não consegue distinguir facilmente os operadores dos operandos. Se $NAMEse parecer com um operador e aparecer em uma posição onde o operador é válido, ele poderá ser analisado como um operador. Isso não acontecerá nos casos simples vistos nesta resposta, mas casos mais complexos podem ser arriscados. Escrever isso com chamadas separadas [e usar os operadores lógicos do shell evita esse problema.

A segunda sintaxe usa a [[ … ]]construção condicional que existe no bash (e ksh e zsh, mas não no sh simples). Esta construção é uma sintaxe especial, embora [seja analisada como qualquer outro comando, portanto, você pode usar coisas como &&inside e não precisa citar variáveis, exceto em argumentos para alguns operadores de string ( =, ==, !=, =~) (consulteQuando as aspas duplas são necessárias?para detalhes).

Responder2

Veja o que mudou a seguir

if [ -r "$NOME"-a -f"$NOME"];então
# ^^^^^ ^
     wc -c "$NOME"
fi

Se você deseja remover todos os comandos do bloco if, você precisa pelo menos adicionar dois pontos nele, como

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

ou versão de uma linha

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

Responder3

Outros já apontaram, mas se você está procurando uma referência oficial entãoRTM

se lista; então liste; [lista de elf; então liste; ] ... [ outra lista;] fi

A lista if é executada. Se o status de saída for zero, a lista then será executada. Caso contrário, cada lista elif será executada por vez e, se seu status de saída for zero, a lista then correspondente será executada e o comando será concluído. Caso contrário, a lista else será executada, se presente. O status de saída é o status de saída do último comando executado ou zero se nenhuma condição for testada como verdadeira.

Você está sentindo falta do;

E a sintaxe paralisté descrito emman test

informação relacionada