You are confusing:
[ -t 0 ]
or test -t 0
, which tests if file descriptor 0 (stdin) is connected to a terminal, as others have already explained
- with
read -t 0
, which tests if there is something to read on stdin (or on the file descriptor specified with the -u
option), without actually reading it
Tests
(read also the caveat section below)
$ echo 'Hello world' | read -t 0
$ echo $?
0
$ read -t 0
$ echo $?
1
$ : | read -t 0
$ echo $?
1
Relevant part of the manual
read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
Read a line from the standard input and split it into fields.
(...)
-t timeout
Time out and return failure if a complete line of input is
not read within TIMEOUT seconds. The value of the TMOUT
variable is the default timeout. TIMEOUT may be a fractional number.
If TIMEOUT is 0, read returns immediately, without
trying to read any data, returning success only if input is
available on the specified file descriptor.
The exit status is greater than 128 if the timeout is exceeded
Caveat
There is an inherent race condition with a construct such as echo something | read -t 0
because, by default, each command in a pipeline is executed as a separate process and you have no control over which process is started first. Moreover, even if echo
is started first, it may be interrupted before it has written anything to stdout.
So, sometimes, read -t0
will return 0 as you may expect, but sometimes read
will be executed before anything is written to the pipe and will return 1.
As suggested by @F.Hauri in comment, you may want to add some delay before testing whether there is something to read, but there is no guarantee this will work every time. Anyway, if you use a non-blocking read, then I assume you expect to retry your read later.
-t
doesn't check if there is input; it checks whether the file handle is connected to atty
(i.e. generally a terminal). If there is a terminal, input could arrive at any time, so in some sense it's the opposite of what you seem to want. – Aldarcieread -t0
is broken in Bash. – Vizzone