User Tools

Site Tools


bash-script-stdio

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.

script.sh
#!/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.

script.sh
#!/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.)

script.awk
#!/bin/awk -f
BEGIN{FS=","} ...

Writing to Stdout and/or to file

To just append script output to the file

script.sh
#!/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.

script.sh
#!/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)
bash-script-stdio.txt · Last modified: 2024/02/19 14:29 by dblume