Vấn đề chung
Tôi muốn viết một kịch bản tương tác với người dùng mặc dù nó ở giữa một chuỗi các đường ống.
Ví dụ cụ thể
Cụ thể, phải mất một file
hoặc stdin
, hiển thị các dòng (có số dòng), yêu cầu người dùng nhập một lựa chọn hoặc số dòng, sau đó in các dòng tương ứng stdout
. Hãy gọi kịch bản này selector
. Về cơ bản, tôi muốn có thể làm
grep abc foo | selector > myfile.tmp
Nếu foo
chứa
blabcbla
foo abc bar
quux
xyzzy abc
sau đó selector
trình bày cho tôi (trên thiết bị đầu cuối, không phải trong myfile.tmp
!) với các tùy chọn
1) blabcbla
2) foo abc bar
3) xyzzy abc
Select options:
sau đó tôi gõ vào
2-3
và kết thúc với
foo abc bar
xyzzy abc
như nội dung của myfile.tmp
.
Tôi đã có một tập lệnh chọn và chạy, và về cơ bản nó đang hoạt động hoàn hảo nếu tôi không chuyển hướng đầu vào và đầu ra. Vì thế
selector foo
cư xử như tôi muốn Tuy nhiên, khi kết hợp các thứ lại với nhau như trong ví dụ trên, hãy selector
in các tùy chọn được trình bày sang myfile.tmp
và cố gắng đọc một lựa chọn từ đầu vào được grepping.
Cách tiếp cận của tôi
Tôi đã thử sử dụng -u
cờ của read
, như trong
exec 4< /proc/$PPID/fd/0
exec 4> /proc/$PPID/fd/1
nl $INPUT >4
read -u4 -p"Select options: "
nhưng điều này không làm những gì tôi hy vọng nó sẽ làm.
Q: Làm thế nào để tôi có được tương tác người dùng thực tế?
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; }'
hoạt động khá tốt. Tuy nhiên grep b foo | selector | wc -l
phá vỡ ở đây. Bất kỳ ý tưởng làm thế nào để khắc phục điều đó? Nhân tiện, cái rangeselect
mà tôi đã sử dụng có thể được tìm thấy tại pastebin.com/VAxTSSHs . Đó là một tập lệnh AWK đơn giản in các dòng của một tệp tương ứng với một phạm vi vải lanh nhất định. (Phạm vi có thể là những thứ như "3-10, 12,14,16-20".)
alias
như vậy, thay selector() { all of that stuff...; }
vào đó là một chức năng. alias
es đổi tên các lệnh đơn giản trong khi các hàm đóng gói một lệnh ghép thành một lệnh đơn giản .