Differences between revisions 1 and 25 (spanning 24 versions)
Revision 1 as of 2009-12-07 00:52:08
Size: 368
Editor: ozgw
Comment:
Revision 25 as of 2020-02-04 18:35:41
Size: 2454
Editor: GreyCat
Comment: *sigh* put the common, simple versions first.
Deletions are marked like this. Additions are marked like this.
Line 2: Line 2:
== How do I process options in a bash script? ==

For example, how do I code my bash script to accept a bunch of options like
== Common utility functions (warn, die) ==
(If you were looking for option processing, see [[BashFAQ/035]].) Bash and sh don't offer a `die` builtin command like Perl does, but it's common to use a `die` function in scripts. You just have to write one yourself. Most people who write a `die` function like to keep it simple. There are two common varieties: one that only takes a message to print, and one that takes a message and an exit status value.
Line 7: Line 6:
foobar -a --busy --include something # Usage: die message ...
die() {
  printf '%s\n' "$*" >&2
  exit 1
}
Line 10: Line 13:
First up, there are some [[http://www.gnu.org/software/libtool/manual/libc/Argument-Syntax.html][GNU and POSIX standards]] for how to do this. {{{
# Usage: die exit_status message ...
die() {
  rc=$1
  shift
  printf '%s\n' "$*" >&2
  exit "$rc"
}
}}}

Some people like fancier functions. If you like fancier functions, here are some variants:

{{{
##
# warn: Print a message to stderr.
# Usage: warn "format" ["arguments"...]
#
warn() {
  local fmt=$1
  shift
  printf "script_name: $fmt\n" "$@" >&2
}

###
### The following three "die" functions
### depend on the above "warn" function.
###

##
# die (simple version): Print a message to stderr
# and exit with the exit status of the most recent
# command.
# Usage: some_command || die "message" ["arguments"...]
#
die () {
  local st=$?
  warn "$@"
  exit "$st"
}

##
# die (explicit status version): Print a message to
# stderr and exit with the exit status given.
# Usage: if blah; then die status_code "message" ["arguments"...]; fi
#
die() {
  local st=$1
  shift
  warn "$@"
  exit "$st"
}

##
# die (optional status version): Print a message to
# stderr and exit with either the given status or
# that of the most recent command.
# Usage: some_command || die [status code] "message" ["arguments"...]
#
die() {
  local st=$?
  if [[ $1 != *[^0-9]* ]]; then
    st=$1
    shift
  fi
  warn "$@"
  exit "$st"
}
}}}


{{{
##
# warn: Print a message to stderr.
# Usage: warn "message"
#
warn() {
  printf '%s\n' "$@" >&2
}

##
# die (optional status version): Print a message to
# stderr and exit with either the given status or
# that of the most recent command.
# Usage: some_command || die "message" [status code]
# some_command && die "message" [status code]

die() {
  local st=$?
  case $2 in
    *[^0-9]*|'') :;;
    *) st=$2;;
  esac
  warn "$1"
  exit "$st"
}
}}}

Since it's your script, you get to decide how fancy you want to make it.

Common utility functions (warn, die)

(If you were looking for option processing, see BashFAQ/035.) Bash and sh don't offer a die builtin command like Perl does, but it's common to use a die function in scripts. You just have to write one yourself. Most people who write a die function like to keep it simple. There are two common varieties: one that only takes a message to print, and one that takes a message and an exit status value.

# Usage: die message ...
die() {
  printf '%s\n' "$*" >&2
  exit 1
}

# Usage: die exit_status message ...
die() {
  rc=$1
  shift
  printf '%s\n' "$*" >&2
  exit "$rc"
}

Some people like fancier functions. If you like fancier functions, here are some variants:

##
# warn: Print a message to stderr.
# Usage: warn "format" ["arguments"...]
#
warn() {
  local fmt=$1
  shift
  printf "script_name: $fmt\n" "$@" >&2
}

###
### The following three "die" functions
### depend on the above "warn" function.
###

##
# die (simple version): Print a message to stderr
# and exit with the exit status of the most recent
# command.
# Usage: some_command || die "message" ["arguments"...]
#
die () {
  local st=$?
  warn "$@"
  exit "$st"
}

##
# die (explicit status version): Print a message to
# stderr and exit with the exit status given.
# Usage: if blah; then die status_code "message" ["arguments"...]; fi
#
die() {
  local st=$1
  shift
  warn "$@"
  exit "$st"
}

##
# die (optional status version): Print a message to
# stderr and exit with either the given status or
# that of the most recent command.
# Usage: some_command || die [status code] "message" ["arguments"...]
#
die() {
  local st=$?
  if [[ $1 != *[^0-9]* ]]; then
    st=$1
    shift
  fi
  warn "$@"
  exit "$st"
}

##
# warn: Print a message to stderr.
# Usage: warn "message"
#
warn() {
  printf '%s\n' "$@" >&2
}

##
# die (optional status version): Print a message to
# stderr and exit with either the given status or
# that of the most recent command.
# Usage: some_command || die "message" [status code]
#        some_command && die "message" [status code]

die() {
  local st=$?
  case $2 in
    *[^0-9]*|'') :;;
    *) st=$2;;
  esac
  warn "$1"
  exit "$st"
} 

Since it's your script, you get to decide how fancy you want to make it.


CategoryShell

BashFAQ/101 (last edited 2020-02-04 18:35:41 by GreyCat)