Essa seria a primeira vez que eu vejo alguém reclamando sobre isso (nós vemos com mais frequência as pessoas reclamando sobre isso não fazendo a divisão da palavra na expansão do parâmetro).
A maioria das pessoas espera
echo $file
para gerar o conteúdo da variável $file
e ficar irritado quando shells como bash
não (um comportamento herdado do shell Bourne, infelizmente não corrigido pelo ksh e especificado pelo POSIX para o interpretador sh
) e isso está causando muitos bugs e vulnerabilidades de segurança e é por isso que você precisa citar todas as variáveis nesses shells.
Veja por exemplo: Implicações de segurança de esquecer de citar uma variável em shells bash / POSIX
Eu vejo que você está esperando isso também porque está escrevendo echo $0
e não echo "$0"
.
zsh
corrigiu isso. Não faz globbing nem quebra de palavras por padrão na expansão de parâmetros. Você precisa solicitá-los explicitamente:
-
echo $=file
: executa a divisão de palavras -
echo $~file
: executar globbing -
echo $=~file
: executa ambos
Ou você pode ativar as opções globsubst
e shwordsplit
para obter o mesmo comportamento de shells semelhantes a Bourne (essas duas opções são ativadas quando zsh
é invocado como sh
para sh
de compatibilidade) , mas eu não recomendaria isso, a menos que você precise de zsh
para interpretar código escrito para outro shell (e, mesmo nesse caso, faria mais sentido interpretar esse código em sh
emulation em um contexto local com emulate -L sh
) .
Aqui, nomeando sua variável file
em
file=*
é enganoso se você pretende expandi-lo após a expansão¹
filename_pattern=*
faria mais sentido. Se você quiser que uma variável contendo o nome de todos os arquivos não ocultos no diretório atual, você faria:
files=(*)
ou:
files=(*(N))
para essa atribuição não falhar se não houver nenhum arquivo não oculto no diretório atual.
Ou seja, use uma atribuição de variável array . Isso funcionaria da mesma forma que em bash
ou ksh93
(de onde vem essa sintaxe) mksh
ou yash
, exceto que zsh
não tem outra falha na característica da Bourne shell pela qual o padrão é deixado não expandido quando não há correspondência.
¹Note que *
é um nome perfeitamente válido para um arquivo no sistema Unix-like. Eu tomo um pouco de conforto em que rm -f -- $file
remove o arquivo cujo nome está armazenado em $file
, mesmo que esse arquivo seja chamado de *
.