IFS nulo não é o mesmo que IFS não definido?

13

Eu li uma ótima pergunta aqui chamada Entendendo o IFS . Fiquei surpreso porque as respostas e comentários citam POSIX, que afirma que IFS = não é o mesmo que desabilitar o IFS. Se você desabilitar o IFS, aparentemente o valor padrão será usado. Se você tornar o IFS nulo, não haverá divisor. Eu sabia que tinha visto uma opinião diferente sobre isso, e achei isso nos meus favoritos:

Programação Bourne Shell

$ IFS

A primeira declaração do seu script deve ser

IFS =

que redefine o separador do campo de entrada para seu valor padrão. Caso contrário, você herdará $ IFS do usuário, que pode ter definido algum valor bizarro para fazer sh shseps de forma diferente da maneira que você espera e induzir um comportamento estranho.

Então isso foi verdade há algum tempo ou o autor está errado?

teste
fonte

Respostas:

20

As respostas que você encontrou no Stack Exchange estão corretas e este tutorial está errado. Você pode experimentar sozinho ou pesquisar no padrão . Um unset IFSé equivalente a defini-lo como o valor padrão de space-tab-newline, enquanto um vazio IFSdesativa efetivamente a divisão de campos.

Você pode consultar a página de Sven Mascheck no IFS sobre implementações históricas. Alguns shells históricos não gostaram unset IFSe uma versão muito antiga do ksh o tratou como um vazio, IFSmas todos os shells modernos e a maioria dos shells antigos tratam um IFSvalor não definido como o valor padrão.

Você não deve iniciar seu script a IFS=menos que queira desativar a divisão de campo (o que pode ser uma decisão razoável - mas observe que você ainda precisa colocar aspas duplas em torno das substituições para evitar globbing, a menos que você o desative set -ftambém). Para redefinir o valor padrão, use unset IFS. É discutível se isso é útil no início de um script; existem muitas outras coisas ruins, como uma desonesta, PATHque o chamador pode fazer para que seu script dê errado.

Este tutorial também recomenda redefinir PATH. Isso geralmente é um mau conselho. Na maioria dos casos, você não pode prever qual é o caminho de pesquisa correto, mas o usuário sabe. Como você sabe se /usr/local/binou /home/bob/bincontém versões de utilitários corrigidas por erros em um unix antigo em que os que /usr/binestão com erros? Deseja realmente incorporar toda a lógica para descobrir se deve /usr/xpg6/binantecipar /bin? Em que posição você quer /usr/gnu/bin? Não redefina PATH, a menos que seu script tenha como alvo um sistema específico.

Não li este tutorial, mas verifiquei uma coisa: desde o início, não é necessário colocar aspas duplas em torno de substituições de variáveis ​​e substituições de comandos. Então, eu não acho que este tutorial seja bom.

Gilles 'SO- parar de ser mau'
fonte
unset IFSnão redefine o IFS para seu valor padrão no bash, mas redefine a divisão de campos.
Melab 7/09/17
O @Melab unset IFSnão redefine IFSseu valor padrão, ele o desativa. Mas um unset IFStem o mesmo efeito que IFSo valor padrão.
Gilles 'SO- stop be evil'