Problema generale
Voglio scrivere uno script che interagisca con l'utente anche se si trova nel mezzo di una catena di pipe.
Esempio concreto
Concretamente, prende un file
o stdin
, visualizza le righe (con i numeri di riga), chiede all'utente di inserire una selezione o numeri di riga, quindi stampa le righe corrispondenti su stdout
. Chiamiamo questo script selector
. Quindi, fondamentalmente, voglio essere in grado di fare
grep abc foo | selector > myfile.tmp
Se foo
contiene
blabcbla
foo abc bar
quux
xyzzy abc
poi selector
mi presenta (sul terminale, non in myfile.tmp
!) con opzioni
1) blabcbla
2) foo abc bar
3) xyzzy abc
Select options:
dopo di che scrivo
2-3
e finiamo con
foo abc bar
xyzzy abc
come contenuto di myfile.tmp
.
Ho uno script selettore attivo e funzionante, e sostanzialmente funziona perfettamente se non reindirizzo input e output. Così
selector foo
si comporta come voglio. Tuttavia, quando si collegano le cose insieme come nell'esempio sopra, selector
stampa le opzioni presentate myfile.tmp
e prova a leggere una selezione dall'input grepped.
Il mio approccio
Ho provato a usare la -u
bandiera di read
, come in
exec 4< /proc/$PPID/fd/0
exec 4> /proc/$PPID/fd/1
nl $INPUT >4
read -u4 -p"Select options: "
ma questo non fa quello che speravo potesse fare.
D: Come posso ottenere l'interazione dell'utente reale?
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; }'
che funziona abbastanza bene. Comunque si grep b foo | selector | wc -l
rompe qui. Qualche idea su come risolverlo? A proposito, quello rangeselect
che ho usato può essere trovato su pastebin.com/VAxTSSHs . È un semplice script AWK che stampa le linee di un file corrispondenti a un determinato intervallo di lino. (Gli intervalli possono essere cose come "3-10, 12,14,16-20".)
alias
, piuttosto selector() { all of that stuff...; }
in una funzione. alias
es rinomina comandi semplici mentre le funzioni racchiudono un comando composto in un singolo comando semplice .