How to read from a file or standard input in Bash How to read from a file or standard input in Bash bash bash

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.

Read more about file descriptor redirection.


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 of echo to avoid printing empty lines when the line consists of a single -e, -n or -E. However there is a workaround by using env POSIXLY_CORRECT=1 echo "$line" which executes your external GNU echo which supports it. See: How do I echo "-e"?

See: How to read stdin when no arguments are passed? at stackoverflow SE