Por que o nullglob afeta a conclusão da tabulação?

7

Depois de shopt -s nullglob , notei que a conclusão da guia parou completamente de funcionar. Por que isso seria? extglob aparentemente é benigno , o que mais poderia afetar o efeito nulo?

Observado em:

  • Ubuntu 14.04 (bash 4.3.11(1)-release )
  • Arch Linux (bash 4.3.42(1)-release )
por muru 16.04.2016 / 20:55

1 resposta

8

Ao contrário de extglob , nullglob faz uma enorme diferença no comportamento do shell. Isso significa que uma palavra contendo caracteres curinga que provavelmente corresponderão a nada resultará em uma palavra desaparecendo em vez de ser mantida.

Na maioria dos casos, o código que quebra com nullglob também seria interrompido sem ele, se um determinado diretório contiver arquivos que correspondam ao padrão sem aspas. Dependendo do padrão, a existência de tais arquivos pode ser mais ou menos provável (e pode ser impossível se os scripts controlarem quais nomes de arquivo estão presentes, por exemplo, porque ele alterna para um diretório temporário que ele preenche).

A conclusão da tabulação do Bash não é afetada pelo nullglob por padrão, mas é afetada se você ativar a conclusão programável, porque alguns dos códigos bash que implementam a conclusão programável não são robustos.

Olhando o que acontece quando concluímos o argumento de ls com set -x ativado, vejo que a saída com e sem nullglob começa a diferir em

+ [[ 0 -gt 0 ]]
+ ref='words[0]'
+ eval 'words[0]=${!ref}${COMP_WORDS[i]}'
++ words[0]=ls
+ line=' '

(trabalhando) vs.

+ [[ 0 -gt 0 ]]
+ ref='words[0]'
+ eval
+ line=' '

com nullglob. Veja que eval line? Isso é um sinal de que o argumento parecia um padrão glob. O código correspondente está na função __reassemble_comp_words_by_ref :

                # Append word separator to current or new word
                ref="$2[$j]"
                eval $2[$j]=\${!ref}\${COMP_WORDS[i]}

[ é um curinga, portanto, $2[$j]=\${!ref}\${COMP_WORDS[i]} é um padrão curinga e, com nullglob , é eliminado, pois não corresponde a nada. Isso também iria quebrar mesmo sem nullglob se o diretório atual contivesse um arquivo chamado words0=${!ref}${COMP_WORDSi} - isso é bem exótico, mas poderia acontecer.

A correção é adicionar as aspas duplas ausentes:

                eval "$2[$j]=\${!ref}\${COMP_WORDS[i]}"

Provavelmente, há outras partes desse script que precisam de correções semelhantes, não investiguei mais.

Este é um bug no bash_completion (não no próprio bash). Foi reportado em 2012 e a correção está no roadmap para a versão 3.0.

    
por 16.04.2016 / 21:18