シェルスクリプトの関数

2016年8月1日(更新: 2016年8月1日)

一連の処理をまとめる(function)

複数の処理をまとめて、呼び出しやすくするには 関数 という仕組みを使います。関数の利点は、まとめた一連の処理を何度でも好きなところで使うことができることです。

関数の作り方

関数の構文を次に示します。

    function 関数名() {
      処理
    }
  

関数名の前に付ける function は省略可能ですが、このページでは省略せずに書きます。

関数の呼び出し

次の例は、複数の文字列を出力する処理を関数にまとめ、それを呼び出すシェルスクリプトです。

    #!/bin/bash

    function print() {
      echo "関数 print を呼び出しました"
      echo "文字列を出力します"
      echo "終了"
    }

    print #これが関数の呼び出し
  

実行結果

関数 print を呼び出しました
文字列を出力します
終了

関数を呼び出すには、呼び出したい部分に呼び出したい関数名を書きます。呼び出す場合は、関数を作るときに必要だった括弧( )は不要です。

次の例では関数 print を複数回呼び出します。

    #!/bin/bash

    function print() {
      echo "関数 print を呼び出しました"
      echo "文字列を出力します"
      echo "終了"
    }

    echo "1回目の呼び出し"
    print
    echo "2回目の呼び出し"
    print
  

実行結果

1回目の呼び出し
関数 print を呼び出しました
文字列を出力します
終了
2回目の呼び出し
関数 print を呼び出しました
文字列を出力します
終了

何度も利用したい処理をまとめておくことで、スクリプトを管理しやすくなります。

関数に引数を渡す

シェルスクリプトに実行時引数を渡したときと同じように、関数にも引数をわたすことができます。関数の引数を利用する場合も、次の表に示す特殊な変数を使います。

変数 意味
${#} 渡したパラメータの数
${@} 渡した全てのパラメータ
${*} ${@}と同じ
${0} 実行しているシェルスクリプトのファイル名
${1} 1つ目に渡したパラメータ
${2} 2つ目に渡したパラメータ
3つめ以降も同様

実際に関数に引数を渡すシェルスクリプトを例を示します。関数に引数を渡す場合も、複数の引数を半角スペースで区切って渡すことができます。次のシェルスクリプトでは、関数 add が2つの引数を受け取り、その和を表示します。

    #!/bin/bash

    function add() {
      echo "2つの引数を足します"
      echo "答えは $((${1} + ${2})) です"
    }

    echo "実行時引数の足し算"
    echo $((${1} + ${2}))

    echo "関数の引数の足し算(1回目)"
    add 2 3

    echo "関数の引数の足し算(2回目)"
    add 5 7
  

実行時入力例(シェルスクリプト名はtest12.sh)

sh test12.sh 1 2

実行結果

実行時引数の足し算
3
関数の引数の足し算(1回目)
2つの引数を足します
答えは 5 です
関数の引数の足し算(2回目)
2つの引数を足します
答えは 12 です

結果からわかるように、関数内で ${1} などを使った場合は関数に渡した引数が呼び出され、関数外で ${1} などを使った場合は実行時引数を呼び出しています。

関数内だけで使える変数(ローカル変数)

関数内だけで利用できて、外部からは呼び出したり書き変えたりできない変数のことをローカル変数といいます。シェルスクリプトでローカル変数を作るときは、変数名の前に local と書きます。次の例は、先ほどの add関数 で得られた答えを、関数内では answer という変数で呼び出せるようにした例です。

    #!/bin/bash

    function add() {
      local answer=$((${1} + ${2}))
      echo "答えは ${answer} です"
    }

    echo "関数の引数の足し算"
    add 2 3

    echo "答えは ${answer} です" #外部から呼び出そうとする
  

外部から呼び出そうとしても失敗し、何も表示されないことが確認できます。

実行結果

関数の引数の足し算
答えは 5 です
答えは です

練習問題

関数を使って、以下の条件を満たすシェルスクリプトを作ってください。

  • 実行すると「来店するお客様の数を入力してください: 」と入力を促すメッセージが表示される。
  • お客様の順番によって注文するものが変わる。
    • 3で割り切れる番号のお客様は100円のハンバーガーを注文する。
    • 3で割って1余る番号のお客様は120円のサラダバーガーを注文する。
    • 3で割って2余る番号のお客様は150円のチキンバーガーを注文する。
  • 以下のような形式でメッセージを表示する。(例: 3を入力した場合)
    来店するお客様の数を入力してください: 3

    1人目のお客様が来ました。
    お客様は サラダバーガー を注文しました。
    お会計 120円 になります。
    ありがとうございました。

    2人目のお客様が来ました。
    お客様は チキンバーガー を注文しました。
    お会計 150円 になります。
    ありがとうございました。

    3人目のお客様が来ました。
    お客様は ハンバーガー を注文しました。
    お会計 100円 になります。
    ありがとうございました。

答えの例(クリックで開く)
    #!/bin/bash

    function shop() {

      local order=""
      local price=0

      # 番号によって注文を変える処理
      if ((${1} % 3 == 0))
      then
        order="ハンバーガー"
        price=100
      elif ((${1} % 3 == 1))
      then
        order="サラダバーガー"
        price=120
      else
        order="チキンバーガー"
        price=150
      fi

      # メッセージを表示する処理
      echo "${1}人目のお客様が来ました。"
      echo "お客様は ${order} を注文しました。"
      echo "お会計 ${price}円 になります。"
      echo "ありがとうございました。"
      echo "" #改行のため
    }

    read -p "来店するお客様の数を入力してください: " max
    echo "" #改行のため
    while :
      do
      customer_number=$((customer_number + 1))

      shop ${customer_number} # 関数の呼び出し

      if ((customer_number == max))
      then
        break
      fi
    done
    

コメントを残す

メールアドレスが公開されることはありません。