Check if no command line arguments and STDIN is empty
Does this fit your requirements ?
#!/bin/sh
if test -n "$1"; then
echo "Read from $1";
elif test ! -t 0; then
echo "Read from stdin"
else
echo "No data provided..."
fi
The major tricks are as follow:
Detecting that you have an argument is done through the
test -n $1
which is checking if a first argument exists.Then, checking if
stdin
is not open on the terminal (because it is piped to a file) is done withtest ! -t 0
(check if the file descriptor zero (akastdin
) is not open).And, finally, everything else fall in the last case (
No data provided...
).
I searched far and wide to no avail, and finally managed to put this together through much trial and error. It has worked flawlessly for me in numerous use-cases ever since.
#!/bin/bash
### LayinPipe.sh
## Recreate "${@}" as "${Args[@]}"; appending piped input.
## Offers usable positional parameters regardless of where the input came from.
##
## You could choose to create the array with "${@}" instead following
## any piped arguments by simply swapping the order
## of the following two 'if' statements.
# First, check for normal positional parameters.
if [[ ${@} ]]; then
while read line; do
Args[${#Args[@]}]="${line}"
done < <(printf '%s\n' "${@}")
fi
# Then, check for piped input.
if [[ ! -t 0 ]]; then
while read line; do
Args[${#Args[@]}]="${line}"
done < <(cat -)
fi
# Behold the glory.
for ((a=0;a<${#Args[@]};a++)); do
echo "${a}: ${Args[a]}"
done
- Example: (knowing full well that using output of 'ls' as input is discouraged in order to show the flexibility of this solution.)
$ ls
: TestFile.txt 'Filename with spaces'
$ ls -1 | LayinPipe.sh "$(ls -1)"
> 0: Filename with spaces
> 1: TestFile.txt
> 2: Filename with spaces
> 3: TestFile.txt
$ LayinPipe.sh "$(ls -1)"
> 0: Filename with spaces
> 1: TestFile.txt
$ ls -1 | LayinPipe.sh
> 0: Filename with spaces
> 1: TestFile.txt