14

I tried to to run echo ${@:$#} and it echoes my current shell.

I found out that echo ${#} echoes 0.

I didn't find any resources about the results.

I am trying to understand that part so I can understand a docker script that I want to use. The script is:

alias enhance='function ne() { docker run --rm -v "$(pwd)/`dirname ${@:$#}`":/ne/input -it alexjc/neural-enhance ${@:1:$#-1} "input/`basename ${@:$#}`"; }; ne'
Jeff Schaller
  • 66,199
  • 35
  • 114
  • 250
tawfikboujeh
  • 143
  • 5
  • 5
    There is no need to encapsulate a function in an alias. It just adds an unnecessary layer. –  Mar 06 '21 at 10:19
  • 1
    (and as another aside, it's more portable not to use the (POSIX-noncompliant, borrowed from legacy ksh for compatibility with pre-POSIX ksh releases but not actually fully compatible with ksh's behavior) `function` keyword at all -- see both entries in the first and last tables in https://wiki.bash-hackers.org/scripting/obsolete; thus, it's better just `ne() { docker run ...; }`, and that'll define a `ne` you can run as-is; no `alias`, no `function`). – Charles Duffy Mar 06 '21 at 15:16

1 Answers1

25

In every POSIX compliant shell,

  • $# is the number of arguments to the function or script, the number of positional parameters.
  • $@ is the list of arguments to the function or script, the list $1, $2, etc. of positional parameters.

In Bash, Ksh and Zsh, etc.:

  • ${@:offset:n} are the n arguments starting at parameter offset, or all arguments to the end from offset if n is missing.

Thus ${@:$#} is the last argument given to the function at hand, whereas ${@:1:$#-1} is the remaining arguments. The last argument could also be written ${@: -1} (in Bash release 4.3 or later).

Quasímodo
  • 18,625
  • 3
  • 35
  • 72
  • 3
    Note that while Bourne's `"$@"` is `"$1" "$2"...`, Korn's `"${@:offset:length}"` also includes `$0` which is not a positional parameter, but the name of the script/function (possibly sourced file). So if `$#` is 0, `${@:$#}` will be that `$0`. For the last argument, see `zsh`/`yash`'s `${@[-1]}` instead (predates the Korn syntax) or even older csh/zsh's `$argv[$#]`, or the POSIX: `eval "last=\${$#}"` – Stéphane Chazelas Mar 06 '21 at 15:05