4

I have a bash script that I mostly use in interactive mode. However, sometimes I pipe in some input to the script. After processing stdin in a loop, I copy a file using "-i" (interactive). However, this never gets executed (in pipe mode) since (I guess) standard input has not been flushed. To simplify with an example:

#!/bin/bash
while read line
do
    echo $line
done
# the next line does not execute 
cp -i afile bfile

Place this in t.sh, and execute with: ls | ./t.sh

The read is not executed. I need to flush stdin before the read. How could it do this?

2 Answers 2

6

This has nothing to do with flushing. Your stdin is the output of ls, you've read all of it with your while loop, so read gets EOF immediately. If you want to read something from the terminal, you can try this:

#!/bin/bash
while read line
do
    echo $line
done
# the next line does execute 
read -p "y/n" x < /dev/tty
echo "got $x"
Sign up to request clarification or add additional context in comments.

4 Comments

I tried both < /dev/tty and < $(tty). Doesn't work, and the second gives an error. ./rtest2.sh: line 122: $(tty): ambiguous redirect Actually, if you see the question, my problem is with a "cp -i" command. The code sample I gave was just demonstrative, since the code itself is large. One could perhaps replace the read command with a cp -i to get the problem
@rahul works equally well with cp -i for me. If it does not work for you, please post your system details (uname -a) and more on how exactly it does not work
I tried it again. Voila. "< dev/tty" has worked ! Thanks a lot.
Would this workd in zsh?
0

I'm not sure it's possible to do what you want here (i.e. having the read take its input from the user and not from ls). The problem is that all standard input for your script is taken from the pipe, period. This is the same file descriptor, so it will not 'switch' to the terminal just because you want it to.

One option would be to run the ls as a child of the script, like this:

#!/bin/bash

ls | while read line
do
    echo $line
done

read -p "y/n" x
echo "got $x"

1 Comment

Sadly, I often use this program directly from the command line without piping input. In that case it works interactively, like a shell prompting me for commands. <p> Some times I pipe in the contents of a file to it through some filters, or i directly grep and sed some content to it through a pipe.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.