leggi con la storia


11

Come posso fare in modo che il readcomando integrato supporti la cronologia, premendo il tasto su / giù per scorrere tra loro?

Ho provato a catturare quando premi il tasto Su, tuttavia non sembra funzionare con read:

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

La pressione dei tasti freccia sembra funzionare e posso rilevarlo usando questo, tuttavia se premo aa, fallirà in quanto leggerà solo il primo carattere dell'identificatore della freccia su, mentre il terzo è necessario per distinguere la diversa freccia chiavi.

Risposte:


8

Puoi usarlo rlwrapper questo, se non ti dispiace installare il software.

Probabilmente vorrai mantenere un file di cronologia separato che mantenga la cronologia solo per il particolare prompt nel tuo script (cioè evita di mescolarti con la cronologia dei comandi della shell dell'utente).

Ecco un esempio che potrebbe funzionare per te:

#!/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

Nello script sopra, l'utente può usare tutte le funzionalità di readline GNU , con la cronologia fornita da - e memorizzata in -  ~/.myscript_history. Modifica se necessario.

In alternativa, puoi usare bash's read -e, che abilita readline per le readinvocazioni, ma probabilmente troverai che la sua funzionalità di cronologia è troppo limitata (cioè quasi inesistente).


10

Per copiare la grande risposta di Mike Stroyan da questo vecchio post della mailing list :

Puoi usare "history -r" per leggere un file nella cronologia della shell e "history -s" per aggiungere ogni riga che leggi nella cronologia. Quindi utilizzare la cronologia -w per salvare la cronologia nel file. Ecco un esempio con l'editing readline in stile 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

Mi piace questa soluzione meglio di rlwrapcome (almeno sulla mia macchina) rlwrapnon è in grado di gestire CTRL-C con grazia, ad esempio provare a correre USERINPUT=$(rlwrap -o cat)e premere CTRL-C e vedere come si comporta il terminale in seguito (eseguire il resetcomando per tornare di nuovo a uno stato sano) .
Zpon,

Funziona davvero bene se non vuoi installare librerie aggiuntive e sei felice di usare un file separato per gestire l'input.
Luke Exton,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.