ปัญหาทั่วไป
ฉันต้องการเขียนสคริปต์ที่โต้ตอบกับผู้ใช้แม้ว่ามันจะอยู่กลางสายโซ่ของท่อ
ตัวอย่างคอนกรีต
รูปธรรมก็จะใช้เวลาfile
หรือstdin
แสดงเส้น (มีหมายเลขบรรทัด) stdout
ขอให้ผู้ใช้ป้อนข้อมูลการเลือกหรือสายตัวเลขและจากนั้นพิมพ์เส้นที่สอดคล้องกับ มาเรียกสคริปต์นี้selector
กัน ถ้าอย่างนั้นฉันก็อยากจะทำ
grep abc foo | selector > myfile.tmp
ถ้าfoo
มี
blabcbla
foo abc bar
quux
xyzzy abc
จากนั้นselector
นำเสนอตัวเลือก (บนเทอร์มินัลไม่ใช่ในmyfile.tmp
!)
1) blabcbla
2) foo abc bar
3) xyzzy abc
Select options:
หลังจากนั้นฉันพิมพ์
2-3
และจบลงด้วย
foo abc bar
xyzzy abc
myfile.tmp
เป็นเนื้อหาของ
ฉันมีสคริปต์ตัวเลือกทำงานอยู่และโดยพื้นฐานแล้วมันจะทำงานได้อย่างสมบูรณ์แบบหากฉันไม่เปลี่ยนเส้นทางอินพุตและเอาต์พุต ดังนั้น
selector foo
ทำงานเหมือนที่ฉันต้องการ อย่างไรก็ตามเมื่อทำการรวมสิ่งต่าง ๆ เข้าด้วยกันดังตัวอย่างข้างต้นให้selector
พิมพ์ตัวเลือกที่นำเสนอไปที่myfile.tmp
และพยายามอ่านสิ่งที่เลือกจากอินพุตที่มีสีเทา
แนวทางของฉัน
ฉันพยายามที่จะใช้-u
ธงของread
เช่นเดียวกับใน
exec 4< /proc/$PPID/fd/0
exec 4> /proc/$PPID/fd/1
nl $INPUT >4
read -u4 -p"Select options: "
แต่นี่ไม่ได้ทำในสิ่งที่ฉันหวังไว้
ถาม:ฉันจะรับการโต้ตอบจากผู้ใช้จริงได้อย่างไร
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; }'
ทำงานได้ดีมาก อย่างไรก็ตามgrep b foo | selector | wc -l
พักที่นี่ ความคิดใดที่จะแก้ไขได้อย่างไร โดยวิธีการrangeselect
ที่ผมใช้สามารถพบได้ที่pastebin.com/VAxTSSHs มันเป็นสคริปต์ AWK ง่าย ๆ ที่พิมพ์บรรทัดของไฟล์ที่ตรงกับชุดของผ้าลินินที่กำหนด (ช่วงสามารถเป็นสิ่งต่าง ๆ เช่น "3-10, 12,14,16-20".)
alias
นั้นแทนที่จะselector() { all of that stuff...; }
เป็นฟังก์ชั่น alias
ES เปลี่ยนชื่อคำสั่งง่ายๆในขณะที่ฟังก์ชั่นแพ็คคำสั่งผสมเป็นหนึ่งคำสั่งง่ายๆ