====== Bash Script Stdin and Stdout ====== ===== Reading from Stdin or Filename ===== If you write a shell script and want it to run with either stdin or a filename, like so: cat file.txt | script.sh script.sh file.txt There are some options. Here we'll use ''awk'' as the command inside the script. === The General, Idiomatic Way === The canonical way is to cat the args to the script. #!/usr/bin/env sh cat "$@" | awk -F, '...' === Shell Default Parameter Substitution === Use Bash parameter substitution to try to pass in ''$1'', but if it doesn't exist, pass in ''/dev/stdin''. #!/usr/bin/env sh awk -F, '...' "${1:-/dev/stdin}" === Let the Command Handle It === Since we're using ''awk'' as our example, and it already supports stdin or filenames, don't be a bash script, be an awk script. (But in this case we can't use ''/usr/bin/env''.) #!/bin/awk -f BEGIN{FS=","} ... ===== Writing to Stdout and/or to file ===== To just append script output to the file #!/usr/bin/env bash set -euf -o pipefail # Just append stdout to the file exec >>file.txt # (now the rest of your script) Or write output to stdout and append the same output to the file. #!/usr/bin/env bash set -euf -o pipefail # Write to stdout and append to the file exec > >(tee -a file.txt) # (now the rest of your script)