Palavras-chave como if , then , else , fi , for , case e assim por diante precisam estar em um local onde o shell espera um nome de comando. Caso contrário, eles são tratados como palavras comuns. Por exemplo,
echo if
imprime apenas if , ele 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 se queixaria se alguma vez fosse executado). O shell continua procurando pelo then e localiza um fi na posição de comando. Como há um if que ainda está procurando por seu then , o fi é inesperado, há um erro de sintaxe.
Você precisa colocar um terminador de comando antes de then para que seja reconhecido como uma palavra-chave. O terminador de comando mais comum é uma quebra de linha, mas antes de then , é comum usar um ponto-e-vírgula (que tem exatamente o mesmo significado que 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 não entende -af . Você supostamente 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 maneira. Eles são operadores do comando [ e precisam ser cada um uma palavra separada (como [ e ] ).
A propósito, embora [ -r "$NAME" -a -f "$NAME" ] funcione, recomendo escrever
[ -r "$NAME" ] && [ -f "$NAME" ]
ou
[[ -r $NAME && -f $NAME ]]
É melhor manter [ … ] condicionais simples porque o comando [ não consegue distinguir facilmente operadores de operando. Se $NAME se parece com um operador e aparece em uma posição onde o operador é válido, ele pode 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 para [ 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 sh simples). Essa construção é sintaxe especial, enquanto [ é analisada como qualquer outro comando, portanto, é possível usar coisas como && dentro e você não precisa citar variáveis, exceto em argumentos para alguns operadores de string ( = , == , != , =~ ) (consulte Quando é necessário fazer uma dupla citação? para detalhes).