Masalah umum
Saya ingin menulis skrip yang berinteraksi dengan pengguna meskipun itu di tengah-tengah rantai pipa.
Contoh nyata
Konkretnya, diperlukan a file
atau stdin
, menampilkan garis (dengan nomor baris), meminta pengguna untuk memasukkan pilihan atau nomor baris, dan kemudian mencetak baris yang sesuai untuk stdout
. Sebut skrip ini selector
. Maka pada dasarnya, saya ingin bisa melakukannya
grep abc foo | selector > myfile.tmp
Jika foo
berisi
blabcbla
foo abc bar
quux
xyzzy abc
kemudian memberi selector
saya (di terminal, bukan di myfile.tmp
!) dengan opsi
1) blabcbla
2) foo abc bar
3) xyzzy abc
Select options:
setelah itu saya ketik
2-3
dan berakhir dengan
foo abc bar
xyzzy abc
sebagai isi myfile.tmp
.
Saya menjalankan skrip pemilih dan menjalankannya, dan pada dasarnya skrip ini berfungsi dengan baik jika saya tidak mengarahkan input dan output. Begitu
selector foo
berperilaku seperti yang saya inginkan. Namun, ketika menyatukan hal-hal seperti pada contoh di atas, selector
mencetak opsi yang disajikan ke myfile.tmp
dan mencoba membaca pilihan dari input yang diterima.
Pendekatan saya
Saya sudah mencoba menggunakan -u
bendera read
, seperti pada
exec 4< /proc/$PPID/fd/0
exec 4> /proc/$PPID/fd/1
nl $INPUT >4
read -u4 -p"Select options: "
tapi ini tidak melakukan apa yang saya harapkan.
T: Bagaimana cara saya mendapatkan interaksi pengguna yang sebenarnya?
cmd | { some processing; read var </dev/tty; } | cmd
alias selector='{ TMPFILE=$(mktemp); cat > $TMPFILE; nl -s") " $TMPFILE | column -c $(tput cols); read -e -p"Select options: " < /dev/tty; rangeselect -v range="$REPLY" $TMPFILE; rm $TMPFILE; }'
yang berfungsi cukup baik. Namun grep b foo | selector | wc -l
istirahat di sini. Ada ide bagaimana cara memperbaikinya? Omong-omong, rangeselect
yang saya gunakan dapat ditemukan di pastebin.com/VAxTSSHs . Ini adalah skrip AWK sederhana yang mencetak garis-garis file yang sesuai dengan sejumlah linenumber tertentu. (Rentang bisa berupa "3-10, 12,14,16-20".)
alias
itu, lebih selector() { all of that stuff...; }
ke fungsi. alias
es mengubah nama perintah sederhana sedangkan fungsi mengemas perintah gabungan menjadi satu perintah sederhana .