Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read from a file or standard input in Bash

Tags:

bash

stdin

People also ask

How do you read standard input?

We can also use fileinput. input() function to read from the standard input. The fileinput module provides utility functions to loop over standard input or a list of files. When we don't provide any argument to the input() function, it reads arguments from the standard input.

What is standard input in bash?

Standard input is used to provide input to a program. (Here we're using the read builtin to read a line from STDIN.) STDOUT root@server~# ls file file. Standard output is generally used for "normal" output from a command. For example, ls lists files, so the files are sent to STDOUT.


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 line
do
  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/bash
less <&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/sh
cat -

Usage:

$ echo test | sh my_script.sh
test

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/bash
while 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/bash
file=${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


I think this is the straightforward way:

$ cat reader.sh
#!/bin/bash
while read line; do
  echo "reading: ${line}"
done < /dev/stdin

--

$ cat writer.sh
#!/bin/bash
for i in {0..5}; do
  echo "line ${i}"
done

--

$ ./writer.sh | ./reader.sh
reading: line 0
reading: line 1
reading: line 2
reading: line 3
reading: line 4
reading: line 5