[[ ! -t 0 ]]
= Does standard input contains anything?
Your premise is wrong. This tests whether stdin is connected to a terminal/tty, not whether stdin contains anything. Because of the negation the command returns 0 (true) if stdin is not connected to a terminal.
See man test
:
-t FD
file descriptor FD
is opened on a terminal
and man bash
:
-t fd
True if file descriptor fd
is open and refers to a terminal.
With this in mind, re-evaluate your examples and you'll see they do indeed return the expected exit status.
The correct way to check if there's anything pending on stdin would be to use select(2)
, but that's not directly available in a shell such as bash
. The closest I can suggest is to use read
with an immediate timeout:
sleep 2
if read -t 0 _
then
echo "Ready to receive data"
IFS= read -r data
echo "Received: $data"
fi
Run this, and then during the initial sleep
, (a) try preloading stdin with some text, (b) do nothing.
Note that this will still hang (on the read -t 0 _
) if you're reading from a pipe and there is no writer present. It will work as I've described if there is a writer present, even if that writer has not written anything to read.