Palavras-chave como if, then, else, fi, for, casee assim por diante necessidade de estar em um lugar onde a Shell espera um nome de comando. Caso contrário, eles são tratados 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 reclamaria se alguma vez fosse executado). O shell continua procurando o thene encontra uma fiposição de comando. Como há um ifque ainda está procurando then, o 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 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 ele não entende -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 maneira. Eles são operadores do [comando e precisam ser cada um uma palavra separada (como faça [e ]).
A propósito, embora [ -r "$NAME" -a -f "$NAME" ]funcione, eu recomendo escrever
[ -r "$NAME" ] && [ -f "$NAME" ]
ou
[[ -r $NAME && -f $NAME ]]
É melhor manter [ … ]condicionais simples, porque o [comando não pode distinguir operadores de operando facilmente. Se $NAMEparecer com um operador e aparecer em uma posição em que o operador é válido, ele poderá ser analisado como 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 existente no bash (e ksh e zsh, mas não sh simples). Esta construção é sintaxe especial, enquanto [é analisado como qualquer outro comando, assim você pode usar coisas como &&dentro e você não precisa variáveis cotação exceto em argumentos para alguns operadores de cordas ( =, ==, !=, =~) (ver Quando é colocar aspas necessário ? para detalhes).