You can check to ensure there is stdin first, and if not, then use a command line argument instead if given:
#!/bin/bash
# Check to see if a pipe exists on stdin.
if [ -p /dev/stdin ]; then
echo "Data was piped to this script!"
# If we want to read the input line by line
while IFS= read line; do
echo "Line: ${line}"
done
# Or if we want to simply grab all the data, we can simply use cat instead
# cat
else
echo "No input was found on stdin, skipping!"
# Checking to ensure a filename was specified and that it exists
if [ -f "$1" ]; then
echo "Filename specified: ${1}"
echo "Doing things now.."
else
echo "No input given!"
fi
fi
Then to test:
Let’s add some stuff to a test.txt file and then pipe the output to our script.
$ printf "stuff\nmore stuff\n" > test.txt
$ cat test.txt | ./testPipe.sh
Output:
Data was piped to this script!
Line: stuff
Line: more stuff
Now let’s test if not providing any input:
$ ./testPipe.sh
Output:
No input was found on stdin, skipping! No input given!
Now let’s test if providing a valid filename:
$ ./testPipe.sh test.txt
Output:
No input was found on stdin, skipping!
Filename specified: test.txt
Doing things now..
And finally, let’s test using an invalid filename:
./testPipe.sh invalidFile.txt
Output:
No input was found on stdin, skipping!
No input given!
Explanation: Programs like read and cat will use the stdin if it is available within the shell, otherwise they will wait for input.
Source: