Extract parameters before last parameter in "$@"

I'm trying to create a Bash script that will extract the last parameter given from the command line into a variable to be used elsewhere. Here's the script I'm working on:

#!/bin/bash
# compact - archive and compact file/folder(s)

eval LAST=\$$#

FILES="$@"
NAME=$LAST

# Usage - display usage if no parameters are given
if [[ -z $NAME ]]; then
  echo "compact <file> <folder>... <compressed-name>.tar.gz"
  exit
fi

# Check if an archive name has been given
if [[ -f $NAME ]]; then
  echo "File exists or you forgot to enter a filename.  Exiting."
  exit
fi

tar -czvpf "$NAME".tar.gz $FILES

Since the first parameters could be of any number, I have to find a way to extract the last parameter, (e.g. compact file.a file.b file.d files-a-b-d.tar.gz). As it is now the archive name will be included in the files to compact. Is there a way to do this?


To remove the last item from the array you could use something like this:

#!/bin/bash

length=$(($#-1))
array=${@:1:$length}
echo $array

Even shorter way:

array=${@:1:$#-1}

But arays are a Bashism, try avoid using them :(.


Portable and compact solutions

This is how I do in my scripts

last=${@:$#} # last parameter 
other=${*%${!#}} # all parameters except the last

EDIT
According to some comments (see below), this solution is more portable than others.
Please read Michael Dimmitt's commentary for an explanation of how it works.


last_arg="${!#}" 

Several solutions have already been posted; however I would advise restructuring your script so that the archive name is the first parameter rather than the last. Then it's really simple, since you can use the shift builtin to remove the first parameter:

ARCHIVENAME="$1"
shift
# Now "$@" contains all of the arguments except for the first