Q1Which notation references the first argument inside a shell function?
Functions — Keeping Repeated Steps in One Place
This article is part of the Linux Course, where you master practical Linux skills from scratch, from basic commands through to shell scripting.
Define logic with name() { ... }, take arguments via $1, keep function-local variables with local, and branch on success with return and $? to reuse the same validation logic — illustrated and practiced in a browser terminal.
Naming a block of logic — defining functions and arguments
Instead of writing the same logic again and again, you can wrap it in a function and call it by name.
Define one with name() { ... }, and put the body between { and }.
After defining it, just write name to run that logic.
This splits a long script into meaningful units, and you only fix things in one place.
To pass values to a function, add arguments after the name when you call it, like name foo bar.
Inside the function, $1 is the first argument and $2 the second (the same notation as the script's own positional parameters).
Wrap an argument in double quotes as "$1", and even a value with spaces is treated as a single argument.
greet() { # define a function
echo "hello, $1"
}
greet alice # hello, alice
greet bob # hello, bob
greet alice bob go into $1 and $2, and the function body uses them to do its work.| Syntax | Meaning | Example |
|---|---|---|
name() { … } | Define a function | greet() { echo "hi $1"; } |
name args | Call a function | greet alice |
$1 | Reference the first argument inside the function | echo "name=$1" |
$2 | Reference the second argument inside the function | echo "port=$2" |
Variables that live only inside a function — local
When you declare local v=... inside a function, that variable is valid only inside the function and disappears when the function returns.
Without local, you overwrite a variable of the same name outside the function too, which causes unexpected side effects.
To reuse a function safely as a component, make the working variables it uses internally local.
msg="outer"
show() {
local msg="inner" # variable only inside the function
echo "in func: $msg"
}
show # in func: inner
echo "outside: $msg" # outside: outer (unchanged outside)
local variable is valid only inside the function. Even with the same name, the outer value does not change.| Syntax | Meaning | Example |
|---|---|---|
local v=… | Create a variable valid only inside the function | local step=1 |
v=… | A variable valid across the whole script | status=ready |
Returning success or failure — return and $?
A function can return an exit code with return N.
By convention 0 means success and anything other than 0 means failure, and right after calling it you can check that value with $?.
Branching directly on a function's success like if check "$x"; then ... makes the flow of validation and processing easier to read.
is_num() {
case "$1" in
*[!0-9]*|"") return 1 ;; # fail if it contains a non-digit or is empty
*) return 0 ;;
esac
}
is_num 12; echo "12 -> $?" # 12 -> 0
is_num abc; echo "abc -> $?" # abc -> 1
return goes into $?, and if branches treating 0 as success and non-zero as failure.| Syntax | Meaning | Example |
|---|---|---|
return 0 | Leave the function as success | is_num 12; # success |
return 1 | Leave the function as failure | is_num abc; # failure |
$? | Check the previous function's return value | is_num 12; echo $? |
if name x; then … | Branch directly on the return value | if is_num "$v"; then …; fi |
Knowledge Check
Answer each question one by one.
Q2What is the scope of a variable declared with local?
Q3Which one checks the return value of the most recent function?