
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 inesperado
fi
Deduzi que meu problema está em minha if
declaração, fazendo if
comentários sobre minhas declarações e adicionando echo "$NAME"
quais exibem os nomes no arquivo /etc/
.
Quando faço alterações, removo #
from if
e fi
adiciono #
to wc -c "$NAME"
, recebo o erro de sintaxe listado acima. Eu adicionei ;
entre ]
então. Também mudei then
para 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 for
diante case
precisam 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 then
e encontra uma fi
posição de comando. Como há um if
que ainda está procurando por seu then
, fi
é inesperado, há um erro de sintaxe.
Você precisa colocar um terminador de comando antes then
para 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 $NAME
se 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