10

I would like to read some data either from pipe or from the command line arguments (say $1), whichever is provided (priority has pipe).

This fragment tells me if the pipe was open or not but I don't know what to put inside in order not to block the script (test.sh) (using read or cat)

if [ -t 0 ]
then
    echo nopipe
    DATA=$1
else
    echo pipe
    # what here?
    # read from pipe into $DATA
fi

echo $DATA

Executing the test.sh script above I should get the following output:

$ echo 1234 | test.sh
1234
$ test.sh 123
123
$ echo 1234 | test.sh 123
1234

1 Answer 1

19

You can read all of stdin into a variable with:

data=$(cat)

Note that what you're describing is non-canonical behavior. Good Unix citizens will:

  1. Read from a filename if supplied as an argument (regardless of whether stdin is a tty)
  2. Read from stdin if no file is supplied

This is what you see in sed, grep, cat, awk, wc and nl to name only a few.


Anyways, here's your example with the requested feature demonstrated:

$ cat script 
#!/bin/bash

if [ -t 0 ]
then
    echo nopipe
    data=$1
else
    echo pipe
    data=$(cat)
fi

echo "$data"

$ ./script 1234
nopipe
1234

$ echo 1234 | ./script
pipe
1234
Sign up to request clarification or add additional context in comments.

Comments

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.