Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have piped a line in bash script and want to check if the pipe has data, before feeding it to a program.

Searching I found about test -t 0 but it doesn't work here. Always returns false. So how to be sure that the pipe has data?


echo "string" | [ -t 0 ] && echo "empty" || echo "fill"

Output: fill

echo "string" | tail -n+2 | [ -t 0 ] && echo "empty" || echo "fill"

Output: fill

Unlike Standard/canonical way to test whether foregoing pipeline produced output? the input needs to be preserved to pass it to the program. This generalizes How to pipe output from one process to another but only execute if the first has output? which focuses on sending email.

share|improve this question
I am surprised nobody mentioned calling poll() with timeout of 0. I am goign to try this right now :) – user113074 May 4 '15 at 21:28
up vote 16 down vote accepted

There's no way to peek at the content of a pipe, nor is there a way to read a character to the pipe then put it back. The only way to know that a pipe has data is to read a byte, and then you have to get that byte to its destination.

So do just that: read one byte; if you detect an end of file, then do what you want to do when the input is empty; if you do read a byte then fork what you want to do when the input is not empty, pipe that byte into it, and pipe the rest of the data.

first_byte=$(dd bs=1 count=1 2>/dev/null | od -t o1 -A n)
if [ -z "$first_byte" ]; then
  # stuff to do if the input is empty
    printf "\\${first_byte# }"
  } | {
    # stuff to do if the input is not empty

The ifne utility from Joey Hess's moreutils runs a command if its input is not empty. It usually isn't installed by default, but it should be available or easy to build on most unix variants. If the input is empty, ifne does nothing and returns the status 0, which cannot be distinguished from the command running successfully. If you want to do something if the input is empty, you need to arrange for the command not to return 0, which can be done by having the success case return a distinguishable error status:

ifne sh -c 'do_stuff_with_input && exit 255'
case $? in
  0) echo empty;;
  255) echo success;;
  *) echo failure;;

test -t 0 has nothing to do with this; it tests whether standard input is a terminal. It doesn't say anything one way or the other as to whether any input is available.

share|improve this answer
OK, thanks. I'll use temp file. I found in the meantime there is ifne command from moreutils deb package that does exactly that, but it's not on my system. – zetah Feb 29 '12 at 11:28
It should be possible to write a ~10-lines C program which uses select(2) to check whether there is data available from a pipe, and use that one for the shell script. Note that this only works for named pipes though. – radiospiel Mar 18 '14 at 20:37
@radiospiel select tells you if a pipe has data now. If the answer is no, it doesn't tell you whether data will come along later. – Gilles Mar 18 '14 at 20:46
IIRC on some Unices (HPUX?), stat(2)/fstat(2) on a pipe gives you (in st_size) how much it contains ATM. – Stéphane Chazelas Mar 18 '14 at 21:43
The first line will make the script wait endlessly if there is no input on stdin. – Suzana_K May 27 '15 at 0:04

You may use test -s /dev/stdin (in an explicit subshell) as well.

# test if a pipe is empty or not
echo "string" | 
    (test -s /dev/stdin && echo 'pipe has data' && cat || echo 'pipe is empty')

echo "string" | tail -n+2 | 
    (test -s /dev/stdin && echo 'pipe has data' && cat || echo 'pipe is empty')

: | (test -s /dev/stdin && echo 'pipe has data' && cat || echo 'pipe is empty')
share|improve this answer
Doesn't work for me. Always says pipe is empty. – amphetamachine Dec 15 '14 at 16:53
Works on my Mac, but not on my Linux box. – peak Jul 5 at 17:45

This seems to be a reasonable ifne implementation in bash if you're ok with reading the whole first line

ifne () {
        read line || return 1
        (echo "$line"; cat) | eval "$@"

echo hi | ifne xargs echo hi =
cat /dev/null | ifne xargs echo should not echo
share|improve this answer
read will also return false if the input is non-empty but contains no newline character, read does some processing on its input and may read more than one line unless you call it as IFS= read -r line. echo can't be used for arbitrary data. – Stéphane Chazelas May 27 '15 at 8:34

Old question, but in case someone comes across it as I did: My solution is to read with a timeout.

while read -t 5 line; do
    echo "$line"

If stdin is empty, this will return after 5 seconds. Otherwise it will read all the input and you can process it as needed.

share|improve this answer

A simple solution is to use ifne command (if input not empty). In some distributions, it is not installed by default. It is a part of the package moreutils in most distros.

ifne runs a given command if and only if the standard input is not empty

Note that if the standard input is not empty, it is passed through ifne to the given command

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.