本文へスキップ
BecomeCoder

シェルスクリプトコース · 第6章 関数と構造化 · レッスン26

引数と戻り値 ― 関数と値をやりとりする

ブラウザで完結

導入

関数から値を持ち帰りたい。ここで多くの人が return を使おうとして混乱します。シェルの return値ではなく成功/失敗を返すもの。値を返したいときは別の方法を使います。

説明

シェルの関数には、2つの「返し方」があります。

返したいもの方法受け取り方
成功/失敗return 0 / return 1if 関数名; then$?
値(文字列・数値)echo 値結果=$(関数名)
#!/bin/bash

# 値を返す: echo して $( ) で受け取る
count_lines() {
  wc -l < "$1"
}

# 成功/失敗を返す: return して if で受け取る
file_exists() {
  if [ -f "$1" ]; then
    return 0
  else
    return 1
  fi
}

lines=$(count_lines logs/app.log)
echo "app.log は $lines 行です"

if file_exists data.csv; then
  echo "data.csv はあります"
else
  echo "data.csv はありません"
fi

return に書けるのは 0〜255 の終了ステータスです。「関数の中で計算した合計」を return で返そうとすると、256以上は化けますし、そもそも文字列は返せません。

値を返すときは echo。呼ぶ側は $( ) で拾う。この形が唯一の正解と思って構いません。

flowchart TD
    A["count_lines logs/app.log"] --> B["関数の中で echo 8"]
    B --> C["$(count_lines …) が 8 を受け取る"]
    C --> D["lines=8"]

注意点として、値を返す関数の中で余計な echo をしないこと。デバッグ用の echo "処理中" が混ざると、それも戻り値の一部になってしまいます。途中経過を出したいときは、標準エラー出力へ(echo "処理中" >&2)逃がします。

やってみよう

スクリプトを実行して、行数の取得と存在チェックが動くことを確かめましょう。次に count_lines logs/access.log に変えて数が変わること、file_exists nothing.csv にして else 側に落ちることを試してください。

演習

count_lines 関数を使って logs/access.log の行数を取得し、アクセスログ: 10 行 と表示してください。

ヒント1を見る

n=$(count_lines logs/access.log) で受け取れます。

ヒント2を見る

echo "アクセスログ: $n 行"

実際に動かしてみよう

本文のサンプルや演習のコードは、コードブロック右上の「コピー」ボタンでコピーして、下のエディタに貼り付ければそのまま実行できます。

シェルスクリプト(シミュレート)

スクリプトを書くエディタと、それを動かす仮想シェルを読み込みます(本物のbashではなく、動きを再現した学習用の環境です)。
スクロールして表示された時点でも自動で読み込まれます。