シェルスクリプト · 2 min read · Dec 07, 2025

シェルスクリプト パートV: Bashにおける関数

こんにちは!HowToForgeのシェルスクリプトチュートリアルシリーズへようこそ。チュートリアルの前のリリースを読みたい場合は、こちらをクリックしてパート1、パート2、パート3、パート4をご覧ください。このパートでは、関数を作成することでスクリプトを効率的に構造化する方法を学びます。このチュートリアルの終わりまでには、Linux Bashシェルで関数を作成し、関数にパラメータを渡し、関数からメインコードに値を返す方法を理解できるようになります。それでは始めましょう!

はじめに

関数は、プログラミング言語におけるサブルーチンとも呼ばれ、特定のタスクをメインルーチンのために実行する命令のセットです[1]。これにより、プログラマーは複雑で長いコードを必要に応じて呼び出すことができる小さなセクションに分割できます。各関数は実行するためにメインルーチンによって呼び出される必要があるため、コードの他の部分とは隔離されており、これによりコードのテストが容易になります。さらに、関数はいつでも繰り返し呼び出すことができるため、コードを再利用、最適化、最小化することができます。ほとんどのプログラミング言語と同様に、bashシェルも関数をサポートしています。

一般的な構文:

  1. 構文1: function function_name { ##### コマンドのセット }
  2. 構文2: function_name() { #### コマンドのセット }

関数の作成

bashは関数のために2つの構造をサポートしています。最初の構文を使用する場合は、キーワードfunctionを使用し、その後に関数名と開きおよび閉じの括弧、波括弧を使用して関数の内容をメインルーチンから分ける必要があります。この構文は、PHPのバックグラウンドがある場合には馴染みがあるでしょう。なぜなら、PHPの関数は同じ方法で宣言されるからです。もう一つの構文は、関数名、開きおよび閉じの括弧、波括弧のみで構成されています。

#!/bin/bash  
myfunction(){  
    echo "My function works!"  
}  
myfunction

シェルスクリプトにおける関数の作成

私たちの例では2番目の構文を使用しました。myfunctionを作成した後、関数名を呼び出すことでメインルーチンに呼び出されました。メインルーチンは、関数の一部として定義されていないスクリプト内のどこにでも存在します。

次に、関数がスクリプト内のどこでも宣言できるかどうかをテストするためにコードを再配置してみましょう。以下のコードを考えてみてください:

#!/bin/bash  
echo "testing my function"  
myfunction  
  
myfunction(){  
    echo "My function works!"  
}

bashにおける関数の作成

上記のコードの3行目は「コマンドが見つかりません」というエラーを返します。これは次のことを意味します:

関数はメインルーチンの前に宣言されている場合にのみ機能します。メインルーチンの後に関数を宣言した場合、インタープリターはエラーを返します。

関数を使用したコードの再構成

関数の最も優れた機能の1つは、コードを再利用できることです。手続きがコマンドを繰り返し実行する必要があるが、ループ文を使用して構造化できない場合、関数が解決策となります。

例えば、以下のコードを考えてみてください:

#!/bin/bash  
while(true)  
do  
    clear  
    printf "次の操作から選択してください: \n"  
    printf "[a]加算\n[b]減算\n[c]乗算\n[d]除算\n"  
    printf "################################\n"  
    read -p "あなたの選択: " choice  
    case $choice in  
    [aA])  
        read -p "最初の整数を入力してください: " int1  
        read -p "2番目の整数を入力してください: " int2  
        res=$((int1+int2))  
   
    ;;  
    [bB])  
        read -p "最初の整数を入力してください: " int1  
        read -p "2番目の整数を入力してください: " int2  
    res=$((int1-int2))  
   
    ;;  
    [cC])  
        read -p "最初の整数を入力してください: " int1  
        read -p "2番目の整数を入力してください: " int2  
        res=$((int1*int2))  
   
    ;;  
    [dD])  
        read -p "最初の整数を入力してください: " int1  
        read -p "2番目の整数を入力してください: " int2  
        res=$((int1/int2))  
   
    ;;  
    *)  
        res=0  
        echo "無効な選択!"  
    esac  
  
    echo "結果は: " $res  
    read -p "続けますか? [y]はい または [n]いいえ: " ans  
    if [ $ans == 'n' ]  
        then  
         echo "スクリプトを終了します。良い一日を!"  
        break  
    else  
        continue  
    fi  
  
done

bashにおけるswitch文

スクリプトは正常に動作していますが、スイッチ文の各パターンで入力を受け付ける行が繰り返されていることに注意してください。

#!/bin/bash  
inputs(){  
     read -p "最初の整数を入力してください: " int1  
    read -p "2番目の整数を入力してください: " int2  
}  
  
exitPrompt(){  
    read -p "続けますか? [y]はい または [n]いいえ: " ans  
    if [ $ans == 'n' ]  
    then  
        echo "スクリプトを終了します。良い一日を!"  
        break  
    else  
        continue  
    fi  
}  
  
while(true)  
do  
    clear  
    printf "次の操作から選択してください: \n"  
    printf "[a]加算\n[b]減算\n[c]乗算\n[d]除算\n"  
    printf "################################\n"  
    read -p "あなたの選択: " choice  
  
    case $choice in  
    [aA])  
        inputs  
        res=$((int1+int2))  
    ;;  
  
    [bB])  
        inputs  
        res=$((int1-int2))  
    ;;  
  
    [cC])  
        inputs  
        res=$((int1*int2))  
    ;;  
  
    [dD])  
        inputs  
        res=$((int1/int2))  
    ;;  
  
    *)  
        res=0  
        echo "無効な選択!"  
    esac  
  
    echo "結果は: " $res  
    exitPrompt  
done

bashにおけるcase文

私たちは、inputsとexitPromptというサブセクションを作成することでコードを改善しました。これは以前のコードと全く同じように動作しますが、現在のコードは適切に構造化されているため、トラブルシューティングが容易です。

関数へのパラメータの渡し方

ほとんどのプログラミング言語と同様に、bashの関数にパラメータを渡し、それらのデータを処理することができます。以下のコードは、シェルスクリプトで値を渡す手順を示しています:

#!/bin/bash  
myfunction(){  
    echo $1  
    echo $2  
}  
  
myfunction "Hello" "World"

bashを使用した関数間の値の渡し方

私たちの例では、myfunctionを呼び出した後に「Hello」と「World」という値を追加しました。これらの値は、パラメータとしてmyfunctionに渡され、ローカル変数に格納されます。ただし、他の言語とは異なり、インタープリターは渡された値を事前定義された変数に格納します。これらの変数は、パラメータの渡し方に応じて名前が付けられ、1が最初の名前で、渡された順序に従います。「Hello」という単語は変数1に格納され、「World」という値は変数2に格納されます。

注意: 例の1と2はローカル変数であり、したがって、パラメータが渡される関数以外のスクリプトの他の部分からはアクセスできません。

例えば、

#!/bin/bash  
myfunction(){  
    echo $1  
    echo $2  
}  
  
myfunction "Hello" "World"  
echo $1  
echo $2

bashスクリプトにおけるパラメータの渡し方

スクリプトの最後の2行のecho $1とecho $2は表示されません。なぜなら、インタープリターは両方の変数を認識しないからです。これらはmyfunctionにローカルです。

関数からの値の返却

関数を作成し、パラメータを渡すことに加えて、bashの関数はキーワードreturnを使用して関数のローカル変数の値をメインルーチンに渡すことができます。返された値はデフォルトの変数$?に格納されます。例えば、以下のコードを考えてみてください:

#!/bin/bash  
add(){  
    sum=$(($1+$2))  
    return $sum  
}  
  
read -p "整数を入力してください: " int1  
read -p "整数を入力してください: " int2  
add $int1 $int2  
echo "結果は: " $?

bashからの関数の値の返却

この例では、int1とint2のパラメータをadd関数に渡します。次に、add関数はsum=$(($1+$2))の行を通じてそれを処理します。次に、sum変数の値はreturn $sumの行を通じてメインルーチンに渡されます。デフォルトでは、$sumの値はデフォルトの変数$?に格納されます。最後に、echo “結果は: “ $?の行が結果を印刷します。

注意: シェルスクリプトは単一の値しか返すことができません。

他のプログラミング言語とは異なり、シェルスクリプトは関数から複数の値を返すことができません。以下の例を見てみましょう:

#!/bin/bash  
add(){  
    sum=$(($1+$2))  
    dif=$(($1-$2))  
    return $sum   
}  
  
read -p "整数を入力してください: " int1  
read -p "整数を入力してください: " int2  
add $int1 $int2  
echo "結果は: " $?  
echo "結果は: " $?

bash関数における値の返却

まとめ

関数を使用し、パラメータを渡し、値を返す別の例を見てみましょう。

#!/bin/bash  
#####################  
#著者: HowtoForge #  
#####################  
   
clear(){  
    clear  
}  
  
bin(){  
    bin1=$(echo "obase=2;$1"|bc)  
    echo $bin1  
}  
  
dec(){  
    dec1=$(echo "ibase=2;$1"|bc)  
    return $dec1  
}  
  
########メイン#########  
    printf "次の操作から選択してください:\n[1]10進数から2進数への変換\n"  
    printf "[2]2進数から10進数への変換\n"  
    read -p "あなたの選択: " op  
    case $op in  
  
    1)  
        read -p "整数を入力してください: " int  
        bin $int  
    ;;  
  
    2)  
        read -p "2進数を入力してください: " int  
        dec $int  
        echo "$intの10進数は$?です"  
    ;;  
  
    *)  
        echo "無効な選択!"  
    esac

bashにおける2進数から10進数への変換

bashにおける10進数から2進数への変換

この例では、与えられた入力を2進数または10進数の値に変換します。$(echo “obase=2;$1”|bc)の行は、与えられた10進数の値を2進数の桁に変換し、bin1変数に格納します。次に、echoコマンドを使用して$bin1の値を表示します。

注意: 10進数から2進数に変換する際は、直接echoを使用する方が良いです。なぜなら、バイナリ値を渡すためにreturnコマンドを使用すると、bashは返す前にバイナリ値を10進数に変換するからです。

さらに、$(echo “ibase=2;$1”|bc)コマンドを使用して2進数の値を10進数に変換しました。

インタープリターは8ビットの2進数桁しか受け付けられないことも覚えておく必要があります。8ビットの制限を超える桁を入力すると、オーバーフローが発生し、桁の最上位ビットが破棄されます。

10ビットの2進数桁1000001010は10を返します。なぜなら、8ビットのルールに従い、右側の残りの2ビット(最上位ビット)が省略されるため、1000001010は00001010と等しくなり、10になります。8ビットを超える2進数桁を受け入れる操作を行いたい場合は、コードを手動で作成する必要があります。

結論

Bashは、ユーザーに多数のツールを提供し、Linuxシステムをより強力にするために、プログラミング言語に非常に似た機能を持っています。このシリーズでは、関数を通じてシェルスクリプトの知識を深めました。シェルスクリプトの関数は、ユーザーにモジュール性を提供し、スクリプトのトラブルシューティングを容易にし、コードの再利用を可能にします。

参考文献:

[1] American Heritage® Dictionary of the English Language, Fifth Edition. Copyright © 2011 by Houghton Mifflin Harcourt Publishing Company. Published by Houghton Mifflin Harcourt Publishing Company.

Share: X/Twitter LinkedIn

新しい投稿を受信箱で受け取る

スパムはありません。いつでも購読を解除できます。