Genel problem
Bir boru zincirinin ortasında olmasına rağmen kullanıcıyla etkileşime giren bir komut dosyası yazmak istiyorum.
Somut örnek
Somut olarak, bir fileveya alır stdin, satırları görüntüler (satır numaraları ile), kullanıcıdan bir seçim veya satır numaraları girmesini ister ve ardından karşılık gelen satırları yazdırır stdout. Bu betik diyelim selector. Sonra temel olarak, yapabilmek istiyorum
grep abc foo | selector > myfile.tmp
Eğer fooiçeriyor
blabcbla
foo abc bar
quux
xyzzy abc
sonra selectorbana seçeneklerle (terminalde değil myfile.tmp!) sunar
1) blabcbla
2) foo abc bar
3) xyzzy abc
Select options:
bundan sonra yazıyorum
2-3
ve sonunda
foo abc bar
xyzzy abc
içeriği olarak myfile.tmp.
Bir seçici komut dosyası var ve çalışıyor ve giriş ve çıkış yönlendirmezseniz temelde mükemmel çalışıyor. Yani
selector foo
istediğim gibi davranıyor. Bununla birlikte, yukarıdaki örnekte olduğu gibi bir şeyleri birbirine bağlarken selector, sunulan seçenekleri yazdırılan myfile.tmpgirdiye yazdırır ve seçili öğeden bir seçim okumaya çalışır.
Benim yaklaşımım
Ben kullanmayı denedim -ubayrağını readolduğu gibi,
exec 4< /proc/$PPID/fd/0
exec 4> /proc/$PPID/fd/1
nl $INPUT >4
read -u4 -p"Select options: "
ama bu umduğum şeyi yapmaz.
S: Gerçek kullanıcı etkileşimini nasıl alabilirim?
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; }'hangisi oldukça iyi çalışıyor. Ancak grep b foo | selector | wc -lburadan kopar. Bunu nasıl düzeltebileceğine dair fikrin var mı? Bu arada, rangeselectkullandığım pastebin.com/VAxTSSHs adresinde bulunabilir . Belirli bir dizi çamaşır grubuna karşılık gelen bir dosyanın satırlarını yazdıran basit bir AWK betiğidir. (Aralık, "3-10, 12,14,16-20" gibi şeyler olabilir.)
aliasziyade o, selector() { all of that stuff...; }bir fonksiyonun içine. aliases basit komutları yeniden adlandırırken , işlevler bir bileşik komutu tek bir basit komut halinde toplar .