3

how to get the last argument passed to a shell script in zsh shell?

$ example.zsh  arg1 arg2 ...  arglast
last argument is "arglast"
Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
Akhil
  • 1,290

1 Answers1

5

@ works mostly¹ like a variable containing the array of positional parameters: $@ can take an array subscript. The last element is at position $# since $# is the number of arguments².

printf 'Last argument is "%s"\n' "${@[$#]}"

Alternatively, in an array subscript, negative values count from the end, so [-1] takes the last element.

printf 'Last argument is "%s"\n' "$@[-1]"

Another way to get the last argument is to use the P parameter expansion flag which does parameter lookup twice: ${(P)foo} takes the value of foo as another parameter name and expands to the value of that. Use this on # which works like a variable that contains the number of positional parameters. Beware however that this only works if there is at least one positional parameter, otherwise you get $0 (the name of the current script). Using the @ array doesn't have this problem.

printf 'Last argument is "%s"\n' "${(P)#}"

¹ The difference is that $@ has an implied @ flag in parameter expansion, so that "$@" and "$@[1,3]" expand to multiple words, like "$array[@]" and "${(@)array[1,3]}".
² Zsh counts both positional parameters and array elements from 1 (unless the ksh_arrays compatibility option is on, in which case array elements count from 0 and the last element would be ${@[${#}-1]}).

  • Note that if there's no positional parameters, ${(P)#} would expand to the contents of $0 (itself not a positional parameter). See also "${@: -1}" (relatively recently added to zsh for compatibility with ksh93/bash) which would expand to nothing (as opposed to one empty string) if there's no positional parameter (allowing you to distinguish between that and the case where the last argument is an empty string, though not when using printf like that). – Stéphane Chazelas Jun 19 '20 at 09:50