Skip to content

Instantly share code, notes, and snippets.

@jay74jung
Created August 31, 2018 00:00
Show Gist options
  • Save jay74jung/20ec33a2baa6bba2bf71714e671ceec2 to your computer and use it in GitHub Desktop.
Save jay74jung/20ec33a2baa6bba2bf71714e671ceec2 to your computer and use it in GitHub Desktop.
#!/bin/sh
# POSIX
# Manual loop
die() {
printf '%s\n' "$1" >&2
exit 1
}
# Usage info
show_help() {
cat << EOF
Usage: ${0##*/} [-hv] [-f OUTFILE] [FILE]...
Do stuff with FILE and write the result to standard output. With no FILE
or when FILE is -, read standard input.
-h display this help and exit
-f OUTFILE write the result to OUTFILE instead of standard output.
-v verbose mode. Can be used multiple times for increased
verbosity.
EOF
}
# Initialize all the option variables.
# This ensures we are not contaminated by variables from the environment.
file=
verbose=0
while :; do
case $1 in
-h|-\?|--help)
show_help # Display a usage synopsis.
exit
;;
-f|--file) # Takes an option argument; ensure it has been specified.
if [ "$2" ]; then
file=$2
shift
else
die 'ERROR: "--file" requires a non-empty option argument.'
fi
;;
--file=?*)
file=${1#*=} # Delete everything up to "=" and assign the remainder.
;;
--file=) # Handle the case of an empty --file=
die 'ERROR: "--file" requires a non-empty option argument.'
;;
-v|--verbose)
verbose=$((verbose + 1)) # Each -v adds 1 to verbosity.
;;
--) # End of all options.
shift
break
;;
-?*)
printf 'WARN: Unknown option (ignored): %s\n' "$1" >&2
;;
*) # Default case: No more options, so break out of the loop.
break
esac
shift
done
# if --file was provided, open it for writing, else duplicate stdout
if [ "$file" ]; then
exec 3> "$file"
else
exec 3>&1
fi
# Rest of the program here.
# If there are input files (for example) that follow the options, they
# will remain in the "$@" positional parameters.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment