ウェブサイト検索

シェル スクリプトの関数の理解と作成 - パート VI


関数はどのプログラミング言語でも重要な役割を果たします。多くの実際のプログラミング言語と同様に、bash には限定された実装で使用される関数があります。

関数とは何ですか?

プログラミングでは、関数は特定のタスクを実行するプログラムの名前付きセクションです。この意味で、関数はプロシージャまたはルーチンの一種です。関数が呼び出されると、プログラムはコードの現在のセクションを離れ、関数内の最初の行の実行を開始します。コードが繰り返される場合、またはタスクが繰り返される場合は、代わりに関数の使用を検討してください。

たとえば、特定のプログラムのいくつかの段階で数値の階乗を見つける必要がある場合を考えてみましょう。 (階乗を計算するための) コード全体を毎回記述する代わりに、階乗を計算するコードの部分をブロック内に一度記述し、同じものを複数回再利用できます。

なぜ関数を書くのでしょうか?

  1. コードを再利用するのに役立ちます。
  2. プログラムの可読性を向上させます。
  3. プログラム内の変数を効率的に使用します。
  4. プログラムを部分ごとにテストできます。
  5. プログラムを一連のサブステップとして表示します。
シェルスクリプト内の関数

シェル スクリプトで関数を記述するための一般的な構文には、次の方法があります。

function func_name {
	. . .
	commands
	. . .
}

or

func_name ( ) {
	. . .
	commands
	. . .
}

Opening curly braces can also be used in the second line as well.

func_name ( )
{
	. . .
	commands
	. . .
}

通常シェル スクリプトで行うように、これらの関数ブロック内に有効なコマンドをいつでも自由に記述できます。ここで、内部に小さな関数を含む単純なスクリプトを 1 つ書いてみましょう。

#!/bin/bash

call_echo ( ) {
	echo ‘This is inside function’
}

op=$1

if [ $# -ne 1 ]; then
	echo "Usage: $0 <1/0>"
else
	if [ $1 = 0 ] ; then
		echo ‘This is outside function’
	elif [ $1 = 1 ] ; then
		call_echo
	else
		echo ‘Invalid argument’
	fi
fi

exit 0

関数定義は、その関数の最初の呼び出しの前に置く必要があります。関数を呼び出す前に「関数を宣言する」ことほど重要なことはありません。また、いつでも関数の中に関数を入れ子にすることができます。

:- 空の関数を記述すると、常に構文エラーが発生します。

同じ関数が複数回定義されている場合、最終バージョンが呼び出されます。例を挙げてみましょう。

#!/bin/bash

func_same ( ) {
	echo ‘First definition’
}

func_same ( ) {
	echo ‘Second definition’
}

func_same

exit 0
パラメータを受け取り、値を返す関数

パラメーターを受け取り、値を返す関数について考えて、さらに深く見てみましょう。関数から値を返すには、組み込みの「return」シェルを使用します。構文は次のとおりです。

func_name ( ) {
	. . .
	commands
	. . .
	return $ret_val
}

同様に、以下のようにスペースで区切って関数に引数を渡すことができます。

func_name $arg_1 $arg_2 $arg_3

関数内では、$1、$2、$3 などの順序で引数にアクセスできます。より明確にするために、関数を使用して最大 2 つの整数を見つける次のサンプル スクリプトを見てください。

#!/bin/bash

USG_ERR=7

max_two ( ) {
	if [ "$1" -eq "$2" ] ; then
		echo 'Equal'
		exit 0
	elif [ "$1" -gt "$2" ] ; then
		echo $1
	else
		echo $2
	fi
}

err_str ( ) {
	echo "Usage: $0 <number1>  <number2>"
	exit $USG_ERR
}

NUM_1=$1
NUM_2=$2
x
if [ $# -ne 2 ] ; then
	err_str
elif [ `expr $NUM_1 : '[0-9]*'` -eq ${#NUM_1} ] ; then
	if [ `expr $NUM_2 : '[0-9]*'` -eq ${#NUM_2} ] ; then  
		max_two $NUM_1 $NUM_2
	else
		err_str
	fi
else
	err_str
fi

exit 0

上記は少し複雑に見えますが、行を読んでいくと簡単です。最初にネストされた if-else if 行は検証目的、つまり正規表現を使用して引数の数と型をチェックするためのものです。その後、2 つのコマンドライン引数を指定して関数を呼び出し、結果をそこに表示します。これは、関数から大きな整数を返すことができないためです。この問題を回避するもう 1 つの方法は、グローバル変数を使用して関数内に結果を格納することです。以下のスクリプトはこの方法を説明しています。

#!/bin/bash

USG_ERR=7
ret_val=

max_two ( ) {
	if [ "$1" -eq "$2" ] ; then
		echo 'Equal'
		exit 0
	elif [ "$1" -gt "$2" ] ; then
		ret_val=$1
	else
		ret_val=$2
	fi
}

err_str ( ) {
	echo "Usage: $0 <number1>  <number2>"
	exit $USG_ERR
}

NUM_1=$1
NUM_2=$2

if [ $# -ne 2 ] ; then
	err_str
elif [ `expr $NUM_1 : '[0-9]*'` -eq ${#NUM_1} ] ; then
	if [ `expr $NUM_2 : '[0-9]*'` -eq ${#NUM_2} ] ; then  
		max_two $NUM_1 $NUM_2
		echo $ret_val
	else
		err_str
	fi
else
	err_str
fi

exit 0

次に、次の関数を使用して、以前のシェル スクリプト シリーズで説明した興味深い問題をいくつか試してみましょう。

  1. 基本的な Linux シェル スクリプト言語のヒントを理解する – パート I
  2. Linux 初心者がシェル プログラミングを学ぶための 5 つのシェル スクリプト – パート II
  3. Linux BASH スクリプトの世界を航海する – パート III
  4. Linux シェル プログラミングの数学的側面 – パート IV
  5. シェルスクリプト言語での数式の計算 - パート V

次のパートでは、ローカル変数の使用、再帰などの機能的機能についてさらに詳しく説明します。コメントで最新情報を入手してください。