Eu esperava não obter nenhuma saída.
Se nullglobfosse o padrão, muitos comandos se comportariam inesperadamente, porque é (talvez infelizmente) comum que os comandos tratem o caso de zero argumentos de nome de arquivo de uma maneira qualitativamente diferente do que o caso de um ou mais argumentos de nome de arquivo.
Suponha que você tenha ativado nullglob( shopt -s nullglob) e esteja em um diretório onde nenhum arquivo corresponde *.txt. Então, *.txtele realmente se expandirá para nada - não um campo vazio, mas nenhum campo - como você esperava. Mas isso teria esses resultados:
ls *.txtlistaria todos os arquivos no diretório atual (exceto arquivos ocultos), porque é o que lsacontece quando você não passa nenhum argumento de nome de arquivo.
cat *.txtleria da entrada padrão , porque quando catnão tem argumentos de nome de arquivo, é como se você tivesse executado cat -. Se estiver executando interativamente, fica aguardando a entrada. Muitos comandos se comportam dessa maneira.
cp *.txt dest/falharia com o erro cp: missing destination file operand after 'dest/'. Isso não é um desastre, mas é confuso e bem diferente do sucesso silencioso que provavelmente é desejado.
file *.txt, e vários outros programas sem comportamento especial para o caso de zero argumentos de nome de arquivo, ainda falhariam com uma mensagem de erro ou uso quando nenhuma delas fosse passada.
- Mesmo casos que, intuitivamente, parecem que deveriam funcionar, normalmente não funcionariam.
printf 'Got file: "%s"\n' *.txtimprimiria em Got file: ""vez de nada.
- Falhas acidentais em citar ocorrências de
*, ?e [que não pretendem ser expandidas pelo shell produziriam com mais frequência resultados obviamente errados, mas de maneiras que podem ser difíceis de descobrir. Por exemplo, se nenhum nome de arquivo no diretório atual fosse iniciado gedit, então apt list gedit*(onde apt list 'gedit*'pretendido) se tornaria justo apt liste listaria todos os pacotes disponíveis.
Portanto, é bom que você não tenha esse comportamento sem solicitá-lo. Provavelmente a situação prática mais comum que é realmente simplificada nullglobé for f in *.txt. Veja também esta pergunta (à qual a resposta de Sergiy Kolodyazhnyy está vinculada).
A pergunta mais difícil de responder é por que - failglobonde é um erro de expansão ter um globo que não corresponde a nenhum arquivo - não é o padrão no bash. Acredito que a resposta de Sergiy Kolodyazhnyy capte a razão disso, mesmo sem abordá-la diretamente. Reter globs não expansíveis sem produzir um erro de expansão é (talvez infelizmente) o comportamento padronizado, e também é um comportamento tradicional e, portanto, esperado. Embora o bash não tente ser totalmente compatível com POSIX, a menos que seja chamado com o nome shou tenha passado a --posixopção, muitas de suas opções de design, mesmo quando não estão no modo POSIX, seguem o POSIX diretamente. Eles tiveram que escolher algum comportamento, e há desvantagens associadas a ir contra as expectativas dos usuários.
Acho que esse é o aspecto menos influente do ponto de vista histórico, então guardei por último ... mas vale a pena mencionar que há algo um pouco conceitualmente estranho no nullglobcomportamento.
nullglobparece elegante a princípio porque, sintaticamente , trata o caso de zero arquivos correspondentes de maneira diferente do caso de um, dois ou qualquer outro número. Os comandos que executamos, nos quais os globs se expandem para argumentos, não tendem a tratá-los da mesma forma, conforme detalhado acima. Mas sintaticamente isso pelo menos parece certo, o que eu acho que é a motivação para sua pergunta.
E, no entanto, há outra inconsistência mais sutil que nullglobnão trata - que ela realmente amplifica. O caso de zero caracteres " globbing " ("curingas") é tratado profundamente diferente do de um, dois ou qualquer outro número. Por exemplo, com shopt -s nullglob, se ab?d?fnão corresponder a nenhum arquivo, ele será removido; se ab?dnão corresponder a nenhum arquivo, ele será removido; mas se abnão corresponder a nenhum arquivo (ou seja, se não houver um arquivo cujo nome seja exatamente ab), ele ainda não será removido. Obviamente, seria um desastre se fosse removido, porque pode não ter a intenção de se referir a um arquivo existente no diretório atual; pode nem se referir a um arquivo. Mas isso ainda elimina qualquer esperança de consistência total.
Os três comportamentos que o bash fornece - o padrão de tratar globs que não correspondem a nenhum arquivo como se eles não fossem globs e transmiti-los sem expansão, o comportamento que você esperava de tratá-los (se você perdoa essa estranha frase) como significando todo o zero dos arquivos que correspondem ( nullglob) e o comportamento seguro de considerá-los erros ( failglob) - todos representam abordagens diferentes para a ambiguidade inerente ao shell, não sendo possível saber se alguma palavra em particular deve ser uma nome do arquivo. O shell executa suas expansões sem o conhecimento de como os comandos específicos que você chama com ele tratarão seus argumentos.
Esse é um dos muitos casos de separação de preocupações . Em sistemas cujo design segue a filosofia do Unix, cada parte tem a intenção de fazer uma coisa e fazê-la bem . O shell processa o texto em comandos e argumentos e chama esses comandos, a maioria dos quais são externos ao próprio shell. Este tende a ser um agradável muito e mais versátil do que os sistemas onde os comandos externos são eles próprios responsáveis por executar essas transformações (como acontece com os processadores de comando tradicionais em DOS e Windows). Mas tem suas desvantagens ocasionais.
shopt -s nullglobproduzirá cadeias vazias para padrões sem correspondência eshopt -u nullglob(configuração padrão) produzirá o próprio padrão.