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 fileo 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 foocontiene
blabcbla
foo abc bar
quux
xyzzy abc
poi selectormi 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, selectorstampa le opzioni presentate myfile.tmpe prova a leggere una selezione dall'input grepped.
Il mio approccio
Ho provato a usare la -ubandiera 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 -lrompe qui. Qualche idea su come risolverlo? A proposito, quello rangeselectche 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. aliases rinomina comandi semplici mentre le funzioni racchiudono un comando composto in un singolo comando semplice .