baca dengan sejarah

11

Bagaimana saya bisa membuat readriwayat mendukung perintah builtin , dengan menekan tombol atas / bawah untuk menggilirnya?

Saya sudah mencoba menangkap ketika Anda menekan tombol atas, namun sepertinya tidak berhasil read:

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

Menekan tombol panah tampaknya berfungsi dan saya dapat mendeteksinya menggunakan ini, namun jika saya menekan aa, itu akan gagal karena hanya akan membaca karakter pertama dari pengidentifikasi panah-atas, sedangkan yang ketiga diperlukan untuk membedakan panah yang berbeda kunci.

Tyilo
sumber

Jawaban:

8

Anda dapat menggunakannya rlwrapuntuk ini, jika Anda tidak keberatan menginstal perangkat lunak.

Anda mungkin ingin menyimpan file histori terpisah yang hanya mempertahankan histori untuk prompt khusus dalam skrip Anda (mis. Hindari pencampuran dengan histori perintah shell pengguna).

Berikut ini contoh yang mungkin cocok untuk Anda:

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

Dalam skrip di atas, pengguna dapat menggunakan semua fungsionalitas readline GNU , dengan riwayat disajikan dari - dan disimpan dalam -  ~/.myscript_history. Tweak sesuai kebutuhan.

Atau, Anda dapat menggunakan bash's read -e, yang memungkinkan readline untuk readpemanggilan, tetapi Anda mungkin akan menemukan fungsionalitas riwayatnya terlalu terbatas (mis. Hampir tidak ada).

mrb
sumber
10

Untuk menyalin jawaban hebat Mike Stroyan dari pos milis lama ini :

Anda dapat menggunakan "history -r" untuk membaca file ke histori shell dan "history -s" untuk menambahkan setiap baris yang Anda baca ke dalam histori. Kemudian gunakan histori -w untuk menyimpan histori kembali ke file. Berikut adalah contoh dengan pengeditan readline gaya 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
Chris Pacejo
sumber
Saya menyukai solusi ini lebih baik daripada rlwrap(setidaknya pada mesin saya) rlwraptidak dapat menangani CTRL-C dengan anggun, misalnya mencoba menjalankan USERINPUT=$(rlwrap -o cat)dan menekan CTRL-C dan melihat bagaimana terminal Anda berperilaku setelah itu (jalankan resetperintah untuk kembali ke keadaan waras lagi) .
zpon
Ini berfungsi dengan sangat baik jika Anda tidak ingin menginstal lib tambahan dan Anda senang menggunakan file terpisah untuk mengelola input.
Luke Exton