Remove last argument from argument list of shell script (bash) Remove last argument from argument list of shell script (bash) shell shell

Remove last argument from argument list of shell script (bash)


I have used this bash one-liner before

set -- "${@:1:$(($#-1))}"

It sets the argument list to the current argument list, less the last argument.


How it works:

  • $# is the number of arguments
  • $((...)) is an arithmetic expression, so $(($#-1)) is one less than the number of arguments.
  • ${variable:position:count} is a substring expression: it extracts count characters from variable starting at position. In the special case where variable is @, which means the argument list, it extracts count arguments from the list beginning at position. Here, position is 1 for the first argument and count is one less than the number of arguments worked out previously.
  • set -- arg1...argn sets the argument list to the given arguments

So the end result is that the argument list is replaced with a new list, where the new list is the original list except for the last argument.


Assuming that you already have an array, you can say:

unset "array[${#array[@]}-1]"

For example, if your script contains:

array=( "$@" )unset "array[${#array[@]}-1]"    # Removes last element -- also see: help unsetfor i in "${array[@]}"; do  echo "$i"done

invoking it with: bash scriptname foo bar baz produces:

foobar


You can also get all but the last argument with

"${@:0:$#}"

which, honestly, is a little sketchy, since it seems to be (ab)using the fact that arguments are numbered starting with 1, not 0.

Update: This only works due to a bug (fixed in 4.1.2 at the latest) in handling $@. It works in version 3.2.