Script Bash - preenchimento automático para entrada do usuário com base nos dados da matriz

3

Em um script bash eu estou lendo alguma entrada do usuário com read . Agora quero fornecer a possibilidade de completar automaticamente a entrada pressionando a tecla Tab .

Exemplo simples: digamos que o usuário digite um nome de um domínio limitado. No script, eu tenho uma matriz contendo todos os nomes válidos, que devem ser incluídos nas sugestões de preenchimento automático.

Eu já tentei algo com a conclusão programável, mas quero que o script seja portátil, ou seja, tudo deve estar neste script. Algo comparável seria o mysql - se você digitar SELECT * FROM e o hit Tab , ele mostrará todas as tabelas disponíveis no banco de dados (e, na verdade, todas as colunas).

Deve funcionar no Mac OS X.

    
por Jakob Benz 23.04.2016 / 21:16

1 resposta

3

Use o rlwrap , um wrapper readline.

De man rlwrap

rlwrap runs the specified command, intercepting user input in order to provide readline's line editing, persistent history and completion.

e da descrição do pacote Debian rlwrap :

This package provides a small utility that uses the GNU readline library to allow the editing of keyboard input for any other command. Input history is remembered across invocations, separately for each command; history completion and search work as in bash and completion word lists can be specified on the command line.

Um script de exemplo muito simples:

#! /bin/bash

ynm=(Yes No Maybe)

reply=$(rlwrap -S 'Do you want to continue? ' -H ~/.jakob.history
        -e '' -i -f <(echo "${ynm[@]}") -o cat)

echo "reply='$reply'"

Isso usa o modo one-shot de rlwrap para executar cat (para obter stdin), mas aceita apenas uma linha de entrada. -o cat is rlwrap é o substituto recomendado para read .

O histórico da linha de comando é armazenado em ~/.jakob.history , e os itens de conclusão estão no array bash $ynm .

rlwrap espera um arquivo como o argumento para a opção -f . Felizmente, podemos usar a subsituição do processo <(echo "${ynm[@]}") para fornecer uma matriz em vez de um arquivo.

-i ativa a insensibilidade a maiúsculas e minúsculas para conclusões.

O -e '' interrompe o rlwrap de acrescentar um espaço após uma conclusão bem-sucedida (para que $reply termine contendo, por exemplo, 'Maybe' em vez de 'Maybe ' com um espaço à direita)

Se você quiser um padrão já pré-digitado na linha de entrada, você pode usar a opção -P ou --pre-given - por exemplo, adicione -P Yes ao comando rlwrap no script de exemplo acima. O usuário teria apenas que pressionar Enter para aceitar ou retroceder ou Ctrl - U para apagar o padrão (como é normal para readline em modo emacs).

veja man rlwrap para detalhes e mais opções. por exemplo. você pode habilitar a conclusão do nome do arquivo com -c ou --complete-filenames .

Verifique se rlwrap está empacotado para sua distro (é para o Debian e provavelmente para o Ubuntu / Mint / etc, pelo menos) antes de baixar e compilar a fonte.

    
por 24.04.2016 / 03:31