Como faço para pesquisar o histórico do bash no modo vi para “foo. * bar”

5

Eu tenho meu ambiente bash no modo vi ( set -o vi ). Então eu posso digitar <ESC>/ seguido por uma palavra, seguido por enter e bash buscas pela palavra no histórico. Como / também é o método do vi para procurar por expressões regulares, eu estava sob a expressão de que o bash também procuraria expressões regulares.

Infelizmente, quando digito <ESC>/foo.*bar no bash, ele não encontra nenhuma linha no histórico que corresponda à expressão regular foo.*bar .

Estou negligenciando algo ou simplesmente não é possível pesquisar no histórico por expressões regulares?

    
por René Nyffenegger 29.06.2016 / 20:56

1 resposta

7

A resposta curta é que você pode não usar expressões regulares para pesquisar o histórico do shell. De acordo com o POSIX (o padrão para sistemas operacionais parecidos com Unix), você deve ser capaz de pesquisar usando o shell regular correspondência de padrões (como usado para globbing de nome de arquivo e com instruções case ). Esse recurso é chamado de pesquisa não incremental , mas atualmente não parece para ser corretamente implementado no Bash.

especificação POSIX

A especificação POSIX para shell Edição de linha de comando (vi-mode) afirma que esses padrões de pesquisa devem usar correspondência de padrão de shell regular. Embora o meta-caracter de ^ seja usado para corresponder ao início de uma linha, eles não são expressões regulares não .

/pattern<newline>

Move backwards through the command history, searching for the specified pattern, beginning with the previous command line. Patterns use the pattern matching notation described in Pattern Matching Notation , except that the '^' character shall have special meaning when it appears as the first character of pattern. In this case, the '^' is discarded and the characters after the '^' shall be matched only at the beginning of a line. Commands in the command history shall be treated as strings, not as filenames.

Implementação Documentada de Bash

O Bash usa a biblioteca GNU Readline para fornecer seus recursos interativos de edição de linhas e pesquisa de histórico. A documentação oficial para a biblioteca Readline se concentra mais no modo Emacs, mas uma pequena seção em seu manual, Readline vi Mode afirma que

While the Readline library does not have a full set of vi editing functions, it does contain enough to allow simple editing of the line.

The Readline vi mode behaves as specified in the POSIX standard.

Implementação de Bash Real

Após vários experimentos em dois sistemas diferentes, descobri que a pesquisa não incremental no Bash / Readline não funciona como descrito em sua documentação oficial. Descobri que * foi tratado como um asterisco literal em vez de um padrão que corresponde a vários caracteres. Da mesma forma, os ? e [ também são tratados como caracteres literais.

Para comparação, eu tentei usar o modo Vi em tcsh e verifiquei se ele implementa corretamente a pesquisa de histórico conforme especificado no padrão POSIX.

Eu então baixei e pesquisei o código da biblioteca Readline e descobri que suas funções de pesquisa de histórico usam uma pesquisa simples de substring e não usam nenhum meta-padrão de padrão de pesquisa - além do cursor, ^ (consulte search.c do repositório git da biblioteca Readline).

Eu presumo que os desenvolvedores do Bash / Readline ainda não implementaram este recurso. Não consegui encontrar uma lista de erros, mas os arquivos CHANGES mostram que eles têm corrigido regularmente problemas relacionados ao modo Vi.

    
por 29.06.2016 / 22:19