Caution
お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。
関数の定義と呼び出し
シェル関数は繰り返し使う処理をひとまとめにして名前を付けます。関数の定義は『function 関数名(){}』または短縮形の『関数名(){}』で書きます。定義した関数はコマンドと同じように呼び出せます。
構文
# 定義方法1(function キーワードあり)
function 関数名() {
処理
}
# 定義方法2(function キーワードなし・POSIX準拠)
関数名() {
処理
}
# 呼び出し
関数名 [引数1] [引数2] ...
# ローカル変数(関数内のみ有効)
local 変数名=値
# 関数の一覧表示
declare -f # 全関数の定義を表示
declare -f 関数名 # 指定した関数の定義を表示
declare -F # 関数名だけを一覧表示
関数の特徴一覧
| 項目 | 概要 |
|---|---|
| 引数の参照 | $1, $2, ... で関数に渡された引数を参照します(スクリプトの引数とは別スコープ)。 |
| local 変数 | local で宣言した変数は関数の外から参照できません。 |
| return | 関数を終了して整数の終了ステータス(0〜255)を返します。 |
| 値の返し方 | 文字列の値は echo で出力し、呼び出し元でコマンド置換($())でキャプチャします。 |
| 再帰呼び出し | 関数は再帰呼び出しできます。 |
| 定義の順序 | 関数は呼び出しより前に定義する必要があります。 |
| unset -f | 定義済みの関数を削除します。 |
サンプルコード
関数を定義して引数を渡します。『local』で関数内のみ有効な変数を宣言します。
#!/bin/bash
greet() {
local name="$1"
echo "こんにちは、${name}さん!"
}
greet "Alice"
greet "Bob"
こんにちは、Aliceさん! こんにちは、Bobさん!
『local』を使わない変数はグローバルスコープなので、関数の外からも参照・変更されます。
counter=0 # グローバル変数
increment() {
local step="${1:-1}" # 引数がなければデフォルト1
counter=$(( counter + step ))
echo "関数内 counter: $counter"
}
increment
increment 5
echo "関数外 counter: $counter"
関数内 counter: 1 関数内 counter: 6 関数外 counter: 6
『return』で終了ステータスを返し、『if』の条件として使います。
file_exists() {
local path="$1"
if [ -f "$path" ]; then
return 0 # 成功(真)
else
return 1 # 失敗(偽)
fi
}
if file_exists "/etc/hosts"; then
echo "/etc/hosts が存在します"
fi
/etc/hosts が存在します
文字列を返すには『echo』で出力し、呼び出し元で『$()』でキャプチャします。
get_timestamp() {
echo "$(date +%Y%m%d_%H%M%S)"
}
ts=$(get_timestamp)
echo "タイムスタンプ: $ts"
タイムスタンプ: 20260306_143022
関数は再帰呼び出しもできます。階乗を計算する例です。
factorial() {
local n=$1
if (( n <= 1 )); then
echo 1
else
local prev=$(factorial $(( n - 1 )))
echo $(( n * prev ))
fi
}
echo "5! = $(factorial 5)"
5! = 120
概要
関数内で定義した変数はデフォルトでグローバルスコープです。意図せずグローバル変数を変更しないよう、関数内では原則として local を使ってください。
シェル関数は終了ステータス(0〜255の整数)しか直接返せません。文字列の値を返すには echo で出力し、呼び出し元でコマンド置換($( ))でキャプチャする慣用パターンを使います。
引数の高度な扱いは 関数の引数と戻り値 を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。