How to read from a file or standard input in Bash
The following solution reads from a file if the script is called with a file name as the first parameter $1
and otherwise from standard input.
while read linedo echo "$line"done < "${1:-/dev/stdin}"
The substitution ${1:-...}
takes $1
if defined. Otherwise, the file name of the standard input of the own process is used.
Perhaps the simplest solution is to redirect standard input with a merging redirect operator:
#!/bin/bashless <&0
Standard input is file descriptor zero. The above sends the input piped to your bash script into less's standard input.
Here is the simplest way:
#!/bin/shcat -
Usage:
$ echo test | sh my_script.shtest
To assign stdin to the variable, you may use: STDIN=$(cat -)
or just simply STDIN=$(cat)
as operator is not necessary (as per @mklement0 comment).
To parse each line from the standard input, try the following script:
#!/bin/bashwhile IFS= read -r line; do printf '%s\n' "$line"done
To read from the file or stdin (if argument is not present), you can extend it to:
#!/bin/bashfile=${1--} # POSIX-compliant; ${1:--} can be used either.while IFS= read -r line; do printf '%s\n' "$line" # Or: env POSIXLY_CORRECT=1 echo "$line"done < <(cat -- "$file")
Notes:
-
read -r
- Do not treat a backslash character in any special way. Consider each backslash to be part of the input line.- Without setting
IFS
, by default the sequences of Space and Tab at the beginning and end of the lines are ignored (trimmed).- Use
printf
instead ofecho
to avoid printing empty lines when the line consists of a single-e
,-n
or-E
. However there is a workaround by usingenv POSIXLY_CORRECT=1 echo "$line"
which executes your external GNUecho
which supports it. See: How do I echo "-e"?
See: How to read stdin when no arguments are passed? at stackoverflow SE