はじめに

この実験では、Linux におけるシェル関数(Shell Functions)について探究します。シェル関数とは、特定のタスクを実行するための再利用可能なコードブロックのことで、これを利用することでスクリプトをより整理され、効率的なものにすることができます。シェルスクリプト内での関数の作成、呼び出し、および引数(パラメータ)の使用方法を学習します。この実験は初心者向けに設計されているため、各コンセプトを一つずつ丁寧に解説していきます。

初めてのシェル関数を作成する

まずは、シンプルなシェル関数を作成することから始めましょう。シェル関数は、大きなスクリプトの中にある「ミニスクリプト」のようなもので、特定のタスクを実行するコマンド群を一つにまとめることができます。

最初に、新しいファイルを作成する必要があります。ターミナルを開き、以下のコマンドを入力してください。

cd ~/project
touch functions.sh

このコマンドで project ディレクトリに移動し、functions.sh という名前の新しいファイルを作成します。このファイルにシェル関数を記述していきます。

では、最初の関数を追加してみましょう。

#!/bin/bash

## これはシンプルな関数です
greet() {
  echo "Hello, World!"
}

## この行で関数を呼び出し(実行)します
greet

内容を詳しく見ていきましょう。

  • 最初の行 #!/bin/bash はシバン(shebang)と呼ばれます。これは、このスクリプトを解釈するために bash を使用するようシステムに伝えます。
  • 関数の定義は greet() { } で行います。波括弧 { } の間にあるものがすべて関数の一部となります。
  • 関数の中には、"Hello, World!" と表示するシンプルな echo コマンドがあります。
  • 最後の行の greet は、定義した関数を呼び出して実行します。

次に、スクリプトに実行権限を与えて実行してみましょう。

chmod +x functions.sh
./functions.sh

以下のように表示されるはずです。

Hello, World!

もしこの出力が表示されない場合は、functions.sh ファイルの内容が正しく入力されているか再度確認してください。

引数を持つ関数

基本的な関数を作成できたので、次は引数(パラメータ)を追加して、より柔軟な関数にしてみましょう。引数を使うことで、関数の中に情報を渡すことができるようになります。

functions.sh ファイルを再度開き、内容を以下のコードに書き換えてください。

#!/bin/bash

## 引数を持つ関数
greet() {
  echo "Hello, $1!"
}

## 複数の引数を持つ関数
calculate() {
  echo "The sum of $1 and $2 is $(($1 + $2))"
}

## 引数を指定して関数を呼び出す
greet "Alice"
calculate 5 3

このコードを解説します。

  • greet 関数内の $1 は、関数に渡された最初の引数を指します。
  • calculate 関数内の $1$2 は、それぞれ 1 番目と 2 番目の引数を指します。
  • $(($1 + $2)) は、2 つの引数の算術加算を行います。

スクリプトを実行します。

./functions.sh

以下のように表示されるはずです。

Hello, Alice!
The sum of 5 and 3 is 8

出力が異なる場合は、ファイルへの変更が正しく保存されているか確認してください。

関数からの戻り値

シェルスクリプトでは、他のプログラミング言語と同じような方法で関数が値を「返す」ことはありません。その代わりに、結果を echo してそれをキャプチャするか、グローバル変数を書き換えるという方法をとります。両方の方法を見てみましょう。

functions.sh を再度開き、内容を以下のコードに更新してください。

#!/bin/bash

## 結果を echo する関数
get_square() {
  echo $(($1 * $1))
}

## グローバル変数を書き換える関数
RESULT=0
set_global_result() {
  RESULT=$(($1 * $1))
}

## echo された結果をキャプチャする
square_of_5=$(get_square 5)
echo "The square of 5 is $square_of_5"

## 関数を使用してグローバル変数を書き換える
set_global_result 6
echo "The square of 6 is $RESULT"

内容の解説:

  • get_square 関数は echo を使って結果を出力し、それを $() 構文を使って変数に格納しています。
  • set_global_result 関数は、スクリプト全体で共有される変数 RESULT を直接書き換えています。
  • $() を使うことで、get_square の出力を変数に「キャプチャ」できます。
  • set_global_result を呼び出すと RESULT が更新されるので、その後に RESULT を表示しています。

ファイルを保存して実行します。

./functions.sh

以下のように表示されるはずです。

The square of 5 is 25
The square of 6 is 36

正しく表示されない場合は、functions.sh ファイルにタイポ(入力ミス)がないか確認してください。

変数のスコープを理解する

シェルスクリプトでは、変数はデフォルトで「グローバル(全体)」です。つまり、スクリプト内のどこからでもアクセスできます。しかし、local キーワードを使用すると、その関数内だけで有効な変数を作成できます。これを「ローカルスコープ」と呼びます。

この概念を理解するために、functions.sh ファイルを修正してみましょう。

内容を以下のコードに更新してください。

#!/bin/bash

## グローバル変数
GLOBAL_VAR="I'm global"

## ローカル変数を持つ関数
demonstrate_scope() {
  local LOCAL_VAR="I'm local"
  echo "Inside function: GLOBAL_VAR = $GLOBAL_VAR"
  echo "Inside function: LOCAL_VAR = $LOCAL_VAR"
}

## 関数を呼び出す
demonstrate_scope

echo "Outside function: GLOBAL_VAR = $GLOBAL_VAR"
echo "Outside function: LOCAL_VAR = $LOCAL_VAR"

このスクリプトで起きていること:

  • グローバル変数 GLOBAL_VAR を定義します。
  • demonstrate_scope 関数の中で、local キーワードを使ってローカル変数 LOCAL_VAR を定義します。
  • 関数内部で両方の変数を表示します。
  • 関数を呼び出した後、関数の外側で再度両方の変数を表示しようと試みます。

ファイルを保存して実行します。

./functions.sh

以下のような出力が表示されるはずです。

Inside function: GLOBAL_VAR = I'm global
Inside function: LOCAL_VAR = I'm local
Outside function: GLOBAL_VAR = I'm global
Outside function: LOCAL_VAR =

関数の外からアクセスしたとき、LOCAL_VAR が空になっていることに注目してください。これは、ローカル変数が定義された関数内でのみ有効であるためです。

応用的な関数 - ENGLISH_CALC

シェル関数の基本をマスターしたので、次は ENGLISH_CALC というより高度な関数を作成してみましょう。この関数は、2 つの数値と演算内容(plus, minus, times)の 3 つの引数を受け取ります。

内容を以下のコードに置き換えてください。

#!/bin/bash

ENGLISH_CALC() {
  local num1=$1
  local operation=$2
  local num2=$3
  local result

  case $operation in
    plus)
      result=$((num1 + num2))
      echo "$num1 + $num2 = $result"
      ;;
    minus)
      result=$((num1 - num2))
      echo "$num1 - $num2 = $result"
      ;;
    times)
      result=$((num1 * num2))
      echo "$num1 * $num2 = $result"
      ;;
    *)
      echo "Invalid operation. Please use 'plus', 'minus', or 'times'."
      return 1
      ;;
  esac
}

## 関数のテスト
ENGLISH_CALC 3 plus 5
ENGLISH_CALC 5 minus 1
ENGLISH_CALC 4 times 6
ENGLISH_CALC 2 divide 2 ## これはエラーメッセージを表示するはずです

この関数のポイント:

  • local 変数を使用して入力値と結果を保存しています。これはグローバル変数との干渉を避けるための良い習慣です。
  • case 文を使用して、異なる演算を処理しています。これは他の言語の switch 文に似ています。
  • 有効な演算ごとに計算を行い、結果を表示します。
  • 無効な演算が指定された場合は、エラーメッセージを表示し、return 1 を返します(シェルスクリプトでは、0 以外の戻り値はエラーを意味します)。
  • 最後に、無効な演算を含むさまざまな入力で関数をテストしています。

ファイルを保存して実行します。

./functions.sh

以下の出力が表示されるはずです。

3 + 5 = 8
5 - 1 = 4
4 * 6 = 24
Invalid operation. Please use 'plus', 'minus', or 'times'.

期待通りの出力にならない場合は、functions.sh ファイルに間違いがないか確認してください。

まとめ

この実験では、Linux におけるシェル関数について、基礎から応用まで学習しました。学んだ内容は以下の通りです。

  1. シンプルな関数の作成と呼び出し
  2. 関数の引数(パラメータ)の扱い方
  3. echo やグローバル変数を使用した関数からの結果の取得
  4. 変数のスコープの理解と local 変数の活用
  5. 算術演算を処理する複雑な関数の作成

シェル関数は、整理された効率的で再利用可能なコードを書くための強力なツールです。複雑なスクリプトを小さく管理しやすい部品に分割することで、理解しやすくメンテナンス性の高いスクリプトを作成できるようになります。

シェル関数をマスターすることで、Linux 環境においてより洗練されたシェルスクリプトを記述し、複雑なタスクを効果的に自動化できるようになります。シェルスクリプトの上達には練習が不可欠です。今回作成した関数を改造したり、日々の業務で遭遇する課題を解決するための独自の関数を作成したりしてみてください。