How to get the last argument to a /bin/sh function

Here's a simplistic way:

print_last_arg () {
  if [ "$#" -gt 0 ]
  then
    s=$(( $# - 1 ))
  else
    s=0
  fi
  shift "$s"
  echo "$1"
}

(updated based on @cuonglm's point that the original failed when passed no arguments; this now echos a blank line -- change that behavior in the else clause if desired)


Given the example of the opening post (positional arguments without spaces):

print_last_arg foo bar baz

For the default IFS=' \t\n', how about:

args="$*" && printf '%s\n' "${args##* }"

For a safer expansion of "$*", set IFS (per @StéphaneChazelas):

( IFS=' ' args="$*" && printf '%s\n' "${args##* }" )

But the above will fail if your positional arguments can contain spaces. In that case, use this instead:

for a in "$@"; do : ; done && printf '%s\n' "$a"

Note that these techniques avoid the use of eval and do not have side-effects.

Tested at shellcheck.net


Although this question is just over 2 years old, I thought I’d share a somewhat compacter option.

print_last_arg () {
    echo "${@:${#@}:${#@}}"
}

Let’s run it

print_last_arg foo bar baz
baz

Bash shell parameter expansion.

Edit

Even more concise: echo "${@: -1}"

(Mind the space)

Source

Tested on macOS 10.12.6 but should also return the last argument on most available *nix flavors...

Hurts much less ¯\_(ツ)_/¯

Tags:

Shell Script