I usually use if [ -t 0 ] to test stdin and if [ -t 1 ] to see if stdin and stdout are TTY's, and if they aren't I assume that they're pipes. I recently learned that that is a bad assumption:
function context()
{
if [ -t 0 ]
then
if [ -t 1 ]
then
echo "no pipes"
else
echo "pipe out only"
fi
else
if [ -t 1 ]
then
echo "pipe in only"
else
echo "pipe in and out"
fi
fi
}
echo "No Loop:" # these cases work as desired
context
echo 'f' | context
echo 'f' | context | cat
context | cat
echo
echo "Loop:"
echo $'foo
bar' | while read x
do
context # I want this to say "no pipes"
echo 'f' | context
done
The output of the above bash is this:
No Loop:
no pipes
pipe in only
pipe in and out
pipe out only
Loop:
pipe in only
pipe in only
pipe in only
pipe in only
How can I change the definition of context to so that the 5th and 7th calls print "no pipes"?
That is, rather than testing whether stdin is not a terminal (which causes the problem) I'd like to test whether stdin for this particular function happens to be a pipe. I see that -p checks to see if it's a named pipe, but I want this for anonymous pipes.
Edit
The actual use case involves a function we'll call theDb in the place of context. Ideally the two cases below would be equivalent regardless of context:
cat file_with_some_sql | theDb
theDb "sql goes here"
context <<<'' >/dev/null).cat ~/.bashrc | while read p; do tr a e; donethe output ofcatis not piped totr. That assumption is false.test -p /dev/stdinworks with "anonymous" pipes:echo yup | if [ -p /dev/stdin ]; then echo yes; fi