General problemI want to write a script that interacts with the user even though it is in the middle of a chain of pipes.Concrete exampleConcretely, it takes a file or stdin, displays lines (with line numbers), asks the user to input a selection or line numbers, and then prints the corresponding lines to stdout. Let's call this script selector. Then basically, I want to be able to dogrep abc foo | selector > myfile.tmpIf foo containsblabcblafoo abc barquuxxyzzy abcthen selector presents me (on the terminal, not in myfile.tmp!) with options1) blabcbla2) foo abc bar3) xyzzy abcSelect options:after which I type in2-3and end up withfoo abc barxyzzy abcas contents of myfile.tmp.I've got a selector script up and running, and basically it is working perfectly if I don't redirect input and output. Soselector foobehaves like I want. However, when piping things together as in the above example, selector prints the presented options to myfile.tmp and tries to read a selection from the grepped input.My approachI've tried to use the -u flag of read, as inexec 4< /proc/$PPID/fd/0exec 4> /proc/$PPID/fd/1nl $INPUT >4read -u4 -pSelect options: but this doesn't do what I hoped it would.Q: How do I get actual user interaction?
How to read user input when using script in pipe
bash;pipe;file descriptors;read;interactive
Using /proc/$PPID/fd/0 is unreliable: the parent of the selector process may not have the terminal as its input.There is a standard path that always refers to the current process's terminal: /dev/tty.nl $INPUT >/dev/ttyread -pSelect options:  </dev/ttyorexec </dev/tty >/dev/ttynl $INPUTread -pSelect options: 