Functions
| Since: | name() { } (POSIX構文) | POSIX(sh互換) |
|---|---|---|
| function name { } (bash拡張構文) | Bash(bash拡張) |
Functions in shell scripts let you group a set of commands under a name and reuse them. There are two definition syntaxes: function name { } and name() { }; both work identically. Arguments are passed at call time as space-separated values, and received inside the function via positional parameters $1, $2, …. There are two ways to "return" a value: return sets the exit status (an integer from 0 to 255 only), while strings or numbers are passed back to the caller by combining echo with command substitution ($()). Variable scope is controlled with the local keyword, which declares a variable that is valid only inside the function.
Definition Syntax
A function can be defined with two syntaxes: one that uses the function keyword, and a POSIX-compliant form that does not. Both write the body inside a { } block, and the function must be defined before it is called.
| Syntax | Description |
|---|---|
function name { } | A bash-specific form. When the function keyword is used, the parentheses () may be omitted. |
name() { } | The POSIX-compliant form. Works with sh as well. This is the most widely used style in bash scripts. |
function name() { } | A form that includes both the function keyword and (). Valid in bash only. |
# -----------------------------------------------
# Two definition syntaxes (both behave the same)
# -----------------------------------------------
# Style 1: with the function keyword (() can be omitted)
function greet {
echo "Hello!"
}
# Style 2: POSIX-compliant (also works with sh)
greet() {
echo "Hello!"
}
# Calling a function (same syntax as a command)
greet
Arguments ($1 $2 $@ $#)
To pass arguments to a function, list the values space-separated at call time. Inside the function, they are received as positional parameters $1, $2, …. These are the same variable names used for script-level arguments, but inside a function they are overridden with the arguments passed to that function.
| Variable | Meaning | Description |
|---|---|---|
$1 $2 … | Positional parameters | Receives the 1st, 2nd, … argument. |
$@ | All arguments (individual elements) | Expands all arguments as separate elements. Quoting it as "$@" correctly handles arguments that contain spaces. |
$* | All arguments (single string) | Expands all arguments as a single string separated by IFS. Use $@ in most cases. |
$# | Number of arguments | Returns the count of arguments passed. Useful for argument validation. |
# -----------------------------------------------
# Receiving arguments
# -----------------------------------------------
# A function that accepts two arguments
show_info() {
# $1 holds the first argument, $2 holds the second
local name="$1"
local grade="$2"
echo "Name: ${name} Grade: ${grade}"
}
# Checking the number of arguments
check_args() {
# Use $# to verify the argument count
if [ "$#" -lt 2 ]; then
echo "Error: not enough arguments (required: 2, received: $#)"
return 1
fi
echo "Arguments received: $@"
}
return vs. echo (how to return a value)
return only sets the function's exit status (an integer from 0 to 255). To pass a string or computed value back to the caller, output it with echo and capture it with $() command substitution.
| Method | What can be returned | How to receive | Description |
|---|---|---|---|
return N | Integer from 0 to 255 only | $? | Returns an exit status indicating success or failure. By convention, 0 means success and 1 or higher means an error. |
echo value | String, number, or multiple lines | $(function_name) | Writes the value to standard output; the caller captures it using command substitution. |
# -----------------------------------------------
# return: sets the exit status (integer 0–255 only)
# -----------------------------------------------
is_valid_grade() {
local grade="$1"
# Check whether the grade is in the range 1–5
if [ "${grade}" -ge 1 ] && [ "${grade}" -le 5 ]; then
return 0 # valid (success)
else
return 1 # invalid (failure)
fi
}
# Receive the exit status via $?
is_valid_grade 3
echo "Exit status: $?" # 0
is_valid_grade 9
echo "Exit status: $?" # 1
# -----------------------------------------------
# echo: passes a string or number to the caller
# -----------------------------------------------
get_greeting() {
local name="$1"
# Use echo to return a string value
echo "Good morning, ${name}"
}
# Capture the function's output with $() command substitution
message=$(get_greeting "Gojo")
echo "${message}"
Scope Control with local
Variables in shell scripts are global by default. Using local inside a function makes that variable valid only within that function. Without local, any variable assignment inside a function affects the entire script.
| Scope | Declaration | Description |
|---|---|---|
| Global | Plain assignment (var=value) | Accessible and modifiable from anywhere in the script, including outside functions. |
| Local | local var=value | Valid only inside the function where it is declared. Discarded when the function returns. |
| Environment variable | export var=value | Inherited by child processes. When exported inside a function, child processes can also read it. |
# -----------------------------------------------
# Without local (the global variable gets modified)
# -----------------------------------------------
name="Gojo" # global variable
change_name_bad() {
# Assigning without local overwrites the global name
name="Fushiguro"
echo "Inside function: ${name}"
}
echo "Before call: ${name}" # Gojo
change_name_bad
echo "After call: ${name}" # Fushiguro ← the global was changed
# -----------------------------------------------
# With local (the global variable is protected)
# -----------------------------------------------
name="Gojo" # global variable
change_name_good() {
# local makes this a function-scoped variable
local name="Fushiguro"
echo "Inside function: ${name}" # Fushiguro
}
echo "Before call: ${name}" # Gojo
change_name_good
echo "After call: ${name}" # Gojo ← the global is unchanged
Sample Code
jjk_function_basic.sh
#!/bin/bash
# -----------------------------------------------
# Demonstrates function definition, arguments,
# return, and echo using Jujutsu Kaisen characters
# -----------------------------------------------
# -----------------------------------------------
# Function: display character information
# Args: $1=name $2=grade $3=technique
# -----------------------------------------------
show_jujutsushi() {
# Verify that exactly 3 arguments were provided
if [ "$#" -ne 3 ]; then
echo "Error: please provide 3 arguments"
return 1
fi
local name="$1"
local grade="$2"
local jutsu="$3"
echo "┌─────────────────────────────┐"
printf "│ Name: %-20s │\n" "${name}"
printf "│ Grade: %-20s │\n" "${grade}"
printf "│ Technique: %-20s │\n" "${jutsu}"
echo "└─────────────────────────────┘"
return 0
}
# -----------------------------------------------
# Function: check whether the grade is Special Grade
# Args: $1=grade string
# return: 0=Special Grade, 1=other
# -----------------------------------------------
is_special_grade() {
local grade="$1"
if [ "${grade}" = "特級" ]; then
return 0 # Special Grade (success)
else
return 1 # Not Special Grade (failure)
fi
}
# -----------------------------------------------
# Function: return a character's title
# Args: $1=name
# echo: outputs the title string
# -----------------------------------------------
get_title() {
local name="$1"
case "${name}" in
"五条悟") echo "Strongest Sorcerer" ;;
"両面宿儺") echo "King of Curses" ;;
"虎杖悠仁") echo "Vessel of Sukuna" ;;
"伏黒恵") echo "Ten Shadows Technique User" ;;
"釘崎野薔薇") echo "Straw Doll Technique User" ;;
*) echo "Sorcerer" ;;
esac
}
# -----------------------------------------------
# Main
# -----------------------------------------------
echo "=== Jujutsu Kaisen Character Encyclopedia ==="
echo ""
# Define character data
declare -a names=("五条悟" "両面宿儺" "虎杖悠仁" "伏黒恵" "釘崎野薔薇")
declare -a grades=("特級" "特級" "1級" "1級補佐" "3級")
declare -a jutsus=("無下限呪術" "解・捌" "発勁" "十種影法術" "芻霊呪法")
for ((i=0; i<${#names[@]}; i++)); do
# Call the function to display character info
show_jujutsushi "${names[$i]}" "${grades[$i]}" "${jutsus[$i]}"
# Use the exit status of return to check for Special Grade
is_special_grade "${grades[$i]}"
if [ "$?" -eq 0 ]; then
echo " * Recognized as a Special Grade sorcerer/curse"
fi
# Capture the title with echo + $()
title=$(get_title "${names[$i]}")
echo " Title: ${title}"
echo ""
done
$ chmod +x jjk_function_basic.sh $ ./jjk_function_basic.sh === Jujutsu Kaisen Character Encyclopedia === ┌─────────────────────────────┐ │ Name: 五条悟 │ │ Grade: 特級 │ │ Technique: 無下限呪術 │ └─────────────────────────────┘ * Recognized as a Special Grade sorcerer/curse Title: Strongest Sorcerer ┌─────────────────────────────┐ │ Name: 両面宿儺 │ │ Grade: 特級 │ │ Technique: 解・捌 │ └─────────────────────────────┘ * Recognized as a Special Grade sorcerer/curse Title: King of Curses ┌─────────────────────────────┐ │ Name: 虎杖悠仁 │ │ Grade: 1級 │ │ Technique: 発勁 │ └─────────────────────────────┘ Title: Vessel of Sukuna ┌─────────────────────────────┐ │ Name: 伏黒恵 │ │ Grade: 1級補佐 │ │ Technique: 十種影法術 │ └─────────────────────────────┘ Title: Ten Shadows Technique User ┌─────────────────────────────┐ │ Name: 釘崎野薔薇 │ │ Grade: 3級 │ │ Technique: 芻霊呪法 │ └─────────────────────────────┘ Title: Straw Doll Technique User
jjk_function_scope.sh
#!/bin/bash
# -----------------------------------------------
# Demonstrates scope control with local
# using Jujutsu Kaisen characters
# -----------------------------------------------
# Global variables: track the current operator and mission count
current_user="(none)"
mission_count=0
# -----------------------------------------------
# Function: execute a mission
# Uses local to protect global variables
# -----------------------------------------------
execute_mission() {
local name="$1" # local variable: valid inside this function only
local mission="$2" # local variable: valid inside this function only
local result="" # local variable: assigned below
# Update the global mission_count
# (no local here because we intentionally modify the global)
mission_count=$((mission_count + 1))
# Set the result based on the character name (assigned to a local variable)
case "${name}" in
"五条悟") result="Sealed with Infinity. Total victory." ;;
"虎杖悠仁") result="Broke through with Sukuna's power. Narrow win." ;;
"伏黒恵") result="Cleared using shikigami. Mission complete." ;;
"釘崎野薔薇") result="Defeated with Straw Doll Technique." ;;
"両面宿儺") result="Annihilated without mercy." ;;
esac
echo " [Mission ${mission_count}] ${name}: ${mission}"
echo " -> ${result}"
}
# -----------------------------------------------
# Function: switch the current operator
# Updates the global variable (no local used)
# -----------------------------------------------
switch_user() {
# No local, so this updates the global current_user
current_user="$1"
echo "Operator changed -> ${current_user}"
}
# -----------------------------------------------
# Main
# -----------------------------------------------
echo "=== Scope check: local variables do not affect globals ==="
echo ""
echo "initial current_user: ${current_user}"
echo "initial mission_count: ${mission_count}"
echo ""
switch_user "五条悟"
execute_mission "五条悟" "Eliminate a Special Grade curse"
switch_user "虎杖悠仁"
execute_mission "虎杖悠仁" "Retrieve a finger of Sukuna"
switch_user "伏黒恵"
execute_mission "伏黒恵" "Release a sealed shikigami"
switch_user "釘崎野薔薇"
execute_mission "釘崎野薔薇" "Destroy a cursed object"
switch_user "両面宿儺"
execute_mission "両面宿儺" "Destroy everything"
echo ""
echo "=== Final state of global variables ==="
echo "current_user: ${current_user} <- updated by switch_user"
echo "mission_count: ${mission_count} <- accumulated by execute_mission"
echo ""
echo "(local variables name / mission / result were discarded when each function returned)"
$ chmod +x jjk_function_scope.sh
$ ./jjk_function_scope.sh
=== Scope check: local variables do not affect globals ===
initial current_user: (none)
initial mission_count: 0
Operator changed -> 五条悟
[Mission 1] 五条悟: Eliminate a Special Grade curse
-> Sealed with Infinity. Total victory.
Operator changed -> 虎杖悠仁
[Mission 2] 虎杖悠仁: Retrieve a finger of Sukuna
-> Broke through with Sukuna's power. Narrow win.
Operator changed -> 伏黒恵
[Mission 3] 伏黒恵: Release a sealed shikigami
-> Cleared using shikigami. Mission complete.
Operator changed -> 釘崎野薔薇
[Mission 4] 釘崎野薔薇: Destroy a cursed object
-> Defeated with Straw Doll Technique.
Operator changed -> 両面宿儺
[Mission 5] 両面宿儺: Destroy everything
-> Annihilated without mercy.
=== Final state of global variables ===
current_user: 両面宿儺 <- updated by switch_user
mission_count: 5 <- accumulated by execute_mission
(local variables name / mission / result were discarded when each function returned)
Summary
Shell script functions can be defined with either function name { } or name() { }. Arguments are passed space-separated at call time and received inside the function using $1, $2, …, $@, and $#. There are two ways to return a value: return for an exit status (integer 0–255) and echo for strings or numbers, where the caller captures the output with $(function_name) command substitution. Because variables are global by default, use local for function-internal variables to prevent unintended side effects on the rest of the script. For argument handling at the script level, see Special Variables as well.
If you find any errors or copyright issues, please contact us.