O preenchimento inesperado da glob Bash usa a primeira correspondência, mesmo que seja ambíguo

3

Se eu tiver os seguintes arquivos em um diretório:

$ ls
a-file-1
b-file-2
something-else

E eu digito

$ cat *file*<TAB>

A linha é inesperadamente atualizada para

$ cat a-file-1 |

(pipe denota cursor) mesmo que o glob também corresponda a b-file-2 . Um pouco estranho é que se eu iniciar outro shell, eu recebo uma listagem de correspondência em double- TAB (que eu prefiro):

$ cat *file*<TAB><TAB>
a-file-1  b-file-2
$ cat *file*|

P: Como esse comportamento é configurado? Eu gostaria de ter o segundo comportamento no shell de login.

Parece que os shells de login estão recebendo o primeiro comportamento, os shells que não fazem login estão recebendo o segundo. No entanto, meu ~/.bash_profile faz pouco mais do que lançar ~/.bashrc . (Eu não tenho um .profile .) Parece que de alguma forma eu devo estar mudando a configuração.

As diferenças de shopt são que somente o shell de login tem extglob on , hostcomplete off e login_shell on , mas alterá-las não altera o comportamento acima. set -o output é o mesmo. Tentei set show-all-if-ambiguous on , mas isso não teve efeito. Estou usando o Ubuntu 14.04.1.

Atualizar em relação a comente por @mpy .

Em um shell que não é de login, quando eu incluo um diretório base no glob e pressiono Alt-G, o comportamento é diferente de quando eu uso a TAB TAB . É este último comportamento específico que eu quero configurar no shell de login.

Alt - G :

$ ls dir/*file*<Alt-G>

atualizações para

$ ls dir/|

removendo o glob e não imprimindo correspondências. Considerando que TAB TAB produz as correspondências

$ ls dir/*file*<TAB><TAB>
a-file-1  b-file-2
$ ls dir/*file*|
    
por G-Wiz 09.10.2014 / 23:58

2 respostas

2

No Ubuntu 14.04, recebo o horrível comportamento de expansão do primeiro jogo por padrão, mas acho que é culpa de algo na conclusão programável.

Depois de um shopt -u progcomp , obtenho o bom comportamento de expansões de lista.

Seu comportamento de shell de login versus não-login provavelmente é devido à obtenção de .bash_profile e /etc/profile , ou não. (Ou seu shell de login NÃO obtém /etc/bash.bashrc ou .bashrc , se seu perfil não der origem a eles / eles.)

update: rastreou o bug na conclusão programável: ativou set -x e examinou a saída de todos os comandos que foram executados depois de atingir TAB . Encontrado onde a expressão glob se transformou em uma lista e descobriu que em /usr/share/bash-completion/bash_completion

O problema estava aqui: (procure por xspec para encontrar essas linhas)

xspec=${1:+"!*.@($1|${1^^})"}
x=$( compgen -f -X "$xspec" -- "$quoted" ) &&

"$quoted" estava sem as aspas, por isso estava sendo expandido lá, nas funções do shell de conclusão do processamento. $quoted é usado dentro de aspas duplas em outras partes do script, então estou bastante confiante de que deveria ser citado, e esse foi o jeito certo de corrigir isso.

reportado como link , esperamos que seja corrigido e faça o seu caminho em todas as distros em breve.

    
por 28.11.2014 / 12:22
3

Além do "$ quoted" não cotado que @ peter-cordes mencionou, há outro bug na função _filedir ():

--- /usr/share/bash-completion/bash_completion--OLD 2015-08-19 19:58:22.734667377 -0500
+++ /usr/share/bash-completion/bash_completion      2016-01-05 15:56:50.442988910 -0500
@@ -604,6 +604,8 @@
         # 2>/dev/null for direct invocation, e.g. in the _filedir unit test
         compopt -o filenames 2>/dev/null
         COMPREPLY+=( "${toks[@]}" )
+    else
+        compopt -o bashdefault 2>/dev/null
     fi
 } # _filedir()

Isso permite que você coma seu bolo e também o tenha: você pode manter o seu "shopc -s progcmp" bash_completion AND se ele não encontrar uma correspondência, ele voltará a usar o bash manipulação de globos padrão.

    
por 05.01.2016 / 22:11