array
The oldest alternative(s) in bash (Since bash 3.0+) are:
$ a=(aa bb cc dd ee)
$ echo "${a[@]:(-1)} ${a[@]: -1} ${a[@]:(~0)} ${a[@]:~0}"
ee ee ee ee
The space is required to avoid the interpretation of :
followed by a minus -
as the expansion of "${var:-abc}"
(Use Default Values).
The ~
is an arithmetic bitwise negation (equivalent to one's complement or flip all bits). From man bash:
ARITHMETIC EVALUATION
! ~ logical and bitwise negation
Since bash-4.2+ also:
$ echo "${a[-1]} ${a[(~0)]}"
ee ee
Since bash 5.0+ also:
$ echo "${a[~0]}"
ee
For all bash versions (older bash):
$ echo "${a[ ${#a[@]}-1 ]}" # spaces added **only** for readability
ee
@
For positional arguments (since bash 2.01):
$ set aa bb cc dd ee
$ echo "${@:(-1)} ${@:~0} ${@: -1} ${@:$#} ${!#}"
ee ee ee ee
A portable solution for all shells is to use eval:
eval printf '"%s\n"' \"\${$#}\"
$@
isn't exactly an array (can't be subscripted). For it, see Getting the last argument passed to a shell script.