Skip to content

Instantly share code, notes, and snippets.

@cometsong
Forked from aaronNGi/newscript.sh
Last active May 11, 2020 20:06
Show Gist options
  • Save cometsong/62a1355553505aa487396cfd9d6a13fa to your computer and use it in GitHub Desktop.
Save cometsong/62a1355553505aa487396cfd9d6a13fa to your computer and use it in GitHub Desktop.
Boilerplate for new POSIX shell scripts
#!/bin/sh
prog_name=${0##*/}
version=0.1
version_text="Boilerplate for new scripts v$version";
options="h q v V d " # basic opts
options+="o: " # script specifics
help_text="Usage: $prog_name [-o <text>] [-hqvV] [<file>]...
${version_text}
-o <text> Set an option with a parameter
-h Display this help text and exit
-q Quiet
-v Verbose mode
-V Display version information and exit
"
### Script variable defaults here:
#opt_o=''
main() {
set_defaults; # nl/cr/tab/esc & traps
parse_options "$@";
shift $((OPTIND-1));
# If we want to use `getopts` again, this has to be set to 1.
OPTIND=1;
# shellcheck disable=2154
{
$opt_o && info "option 'o' has value '$val_o'";
$opt_h && usage;
$opt_V && version;
$opt_q && info() { :; }
$opt_d || debug() { :; }
$opt_v && info "verbose mode is on";
}
_i=1;
for _file do
info "operand $_i is '$_file'";
_i=$((_i+1));
done
unset _i _file;
[ -t 0 ] || info "stdin is not a terminal";
}
##########################################################################
# shellcheck disable=2034,2046
set_defaults() {
set -e;
trap 'clean_exit' EXIT TERM;
trap 'clean_exit HUP' HUP;
trap 'clean_exit INT' INT;
IFS=' ';
set -- $(printf '\n \r \t \033');
nl=$1 cr=$2 tab=$3 esc=$4;
IFS=\ $tab;
}
# For a given optstring, this function sets the variables
# "opt_<optchar>" to true/false and val_<optchar> to its parameter.
parse_options() {
for _opt in $options; do
# The POSIX spec does not say anything about spaces in the
# optstring, so lets get rid of them.
_optstring=$_optstring$_opt;
eval "opt_${_opt%:}=false";
done
while getopts ":$_optstring" _opt; do
case $_opt in
:) usage "option '$OPTARG' requires a value" ;;
\?) usage "unrecognized option '$OPTARG'" ;;
*)
eval "opt_$_opt=true";
[ -n "$OPTARG" ] &&
eval "val_$_opt=\$OPTARG";
;;
esac
done
unset _opt _optstring OPTARG;
}
datestamp() {
_format=${*:-"%Y-%m-%d %H:%M:%S%z"};
echo $(date +"$_format");
}
info() { printf '%b\n' "$*"; }
debug() { info 'DEBUG: ' "$*" >&2; }
version() { info "$version_text"; exit; }
error() {
_error=${1:-1};
shift;
printf '%s: Error: %s\n' "$prog_name" "$*" >&2;
exit "$_error";
}
usage() {
[ $# -ne 0 ] && {
exec >&2;
printf '%s: %s\n\n' "$prog_name" "$*";
}
printf %s\\n "$help_text";
exit ${1:+1};
}
clean_exit() {
_exit_status=$?;
trap - EXIT;
info "exiting";
[ $# -ne 0 ] && {
trap - "$1";
kill -s "$1" -$$;
}
exit "$_exit_status";
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment