Typically At-Symbol (@) Is Better Than Star (*) for argument passing in Shell

TLDR: Default to "${@}" for argument passing between functions in shell.

Content

Typically "${@}" is what you want when you want to pass arguments from one bash function to another.

@ symbol retains the separation between arguments while * puts them together.

Example code

foo() {
  local num_args="$#"
  echo "Number of arguments: $num_args"
  echo "arg1: ${1:-<empty>}"
  echo "arg2: ${2:-<empty>}"
  echo "arg3: ${3:-<empty>}"
}

# shellcheck disable=SC2016
main() {
  echo.bold '"${@}"'
  foo "${@}"

  echo.bold '"${*}"'
  foo "${*}"
}

main "${@}" || exit 1

When we run this with separate arguments we see that "${*}" has combined arguments into 1.

❯sr 1 2 3
"${@}"
Number of arguments: 3
arg1: 1
arg2: 2
arg3: 3

"${*}"
Number of arguments: 1
arg1: 1 2 3
arg2: <empty>
arg3: <empty>

Backlinks