leia com história


11

Como posso fazer com que o readcomando interno suporte o histórico, pressionando a tecla para cima / para baixo para alternar entre eles?

Eu tentei pegar quando você pressiona a tecla para cima, mas parece que não funciona read:

read -p '> ' -n 3 foo
echo
echo -n "$foo" | hexdump

Pressionar as teclas de seta parece funcionar e eu posso detectá-lo usando isso; no entanto, se eu pressionar aa, ele falhará, pois só lerá o primeiro caractere do identificador da seta para cima, enquanto o terceiro é necessário para distinguir as diferentes setas. chaves.

Respostas:


8

Você pode usar rlwrapisso se não se importar em instalar o software.

Você provavelmente desejará manter um arquivo de histórico separado que apenas mantenha histórico para o prompt específico em seu script (ou seja, evite misturar com o histórico de comandos do shell do usuário).

Aqui está um exemplo que pode funcionar para você:

#!/bin/sh
# Save in rlwrap_example.sh

HISTORY=$HOME/.myscript_history
USERINPUT=$(rlwrap -H $HISTORY sh -c 'read REPLY && echo $REPLY')
echo "User said $USERINPUT"

$ ./rlwrap_example.sh
hello
User said hello

No script acima, o usuário pode usar toda a funcionalidade de linha de leitura do GNU , com o histórico servido em - e armazenado em -  ~/.myscript_history. Ajuste conforme necessário.

Como alternativa, você pode usar o bash's read -e, que habilita a linha de leitura para readinvocações, mas provavelmente encontrará a funcionalidade do histórico muito limitada (por exemplo, quase inexistente).


10

Para copiar a ótima resposta de Mike Stroyan dessa antiga postagem na lista de discussão :

Você pode usar "history -r" para ler um arquivo no histórico do shell e "history -s" para adicionar cada linha que você lê no histórico. Em seguida, use history -w para salvar o histórico novamente no arquivo. Aqui está um exemplo com a edição de linha de leitura no estilo vi.

#!/bin/bash
history -r script_history
set -o vi
CMD=""
while true
do
    echo "Type something"
    read -e CMD
    history -s "$CMD"
    echo "You typed $CMD"
    case "$CMD" in
        stop)
            break
            ;;
        history)
            history
            ;;
    esac
done
history -w script_history
echo stopping

Eu gosto mais desta solução do que rlwrapporque (pelo menos na minha máquina) rlwrapé incapaz de lidar com o CTRL-C normalmente, por exemplo, tente executar USERINPUT=$(rlwrap -o cat)e pressionar CTRL-C e veja como o seu terminal se comporta depois (execute o resetcomando para retornar a um estado sadio novamente) .
zpon

Isso funciona muito bem se você não deseja instalar bibliotecas adicionais e está feliz em usar um arquivo separado para gerenciar as entradas.
Luke Exton
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.