← Back to Bash Course | Chapter 5: Functions | Lesson 4 of 11

Function Parameters

Functions receive the values they were called with as positional parameters, $1, $2, and so on, exactly the same way a whole script receives command-line arguments.

Accessing Arguments with $1, $2...

When a function is called with arguments, those values become the function's own $1, $2, and so on for the duration of that call, just like a script's command-line arguments. This lets a single function behave differently depending on what it's given.

Example: Accessing Arguments with $1, $2...

bash
#!/bin/bash
greet() {
    echo "Hello, $1! You are $2 years old."
}
greet "Ada" 36

Counting Arguments with $#

$# inside a function tells you exactly how many arguments were passed to that particular call, which is useful for validating input before using it. This count is scoped to the function -- it does not reflect the script's own top-level argument count.

Example: Counting Arguments with $#

bash
#!/bin/bash
sum_two() {
    if [ "$#" -ne 2 ]; then
        echo "Error: expected exactly 2 arguments, got $#"
        return 1
    fi
    echo "Sum: $(( $1 + $2 ))"
}
sum_two 3 4
sum_two 3 || echo "Handled the argument-count error gracefully"

Forwarding All Arguments with "$@"

"$@" inside a function expands to every argument passed to that function, each one preserved as its own separate word, which is the correct way to forward all arguments to another command. This works the same way for functions as it does for whole scripts.

Example: Forwarding All Arguments with "$@"

bash
#!/bin/bash
log_message() {
    echo "[LOG] $*"
}
notify_all() {
    log_message "$@"
}
notify_all "System" "started successfully"

Default Values for Missing Parameters

Just like with script arguments, a function can use ${1:-default} style parameter expansion to supply a fallback whenever the caller omits an argument. This avoids errors from referencing an unset positional parameter.

Example: Default Values for Missing Parameters

bash
#!/bin/bash
set_volume() {
    local level="${1:-50}"
    echo "Volume set to $level"
}
set_volume 80
set_volume
Common Mistakes
  1. Assuming a function can access the caller's local variables by name automatically; unless explicitly passed as an argument (or the variable is global), a function only sees what is given to it via $1, $2, etc.
  2. Confusing a function's $1 with the script's own $1; inside a function, the positional parameters are temporarily replaced with the function's own call arguments, shadowing the script-level ones for the duration of the call.
  3. Forgetting to quote "$@" when forwarding a function's arguments to another command, causing arguments with spaces to be split apart.
Chapter Summary
  • Inside a function, $1, $2, ... refer to that function's own arguments, not the script's original command-line arguments.
  • $# inside a function gives the number of arguments passed to that specific function call.
  • "$@" inside a function expands to all of that function's arguments, each preserved as a separate word when quoted.
  • Functions do not require declaring parameter names ahead of time -- you simply reference $1, $2, etc. wherever needed in the body.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.