この記事のポイント
・bashの関数は function 名前() { 処理; } で定義する
・関数を定義したシェル内でだけ利用でき、別ターミナルには引き継がれない
・declare -f で定義済み関数一覧、unset で関数を削除できる
・.bashrc に書けば常用関数として永続化できる
そんなときに役立つのが 関数(function) の定義です。
この記事では、bashで 関数を定義する 基本書式から、引数の受け取り方、定義済み関数の確認・削除、.bashrc への永続化まで、現場でそのまま使える形で解説します。
シェルスクリプトを書き始めたばかりの方でも、読み終えたあとに自分専用の関数をすぐに作れるレベルを目指します。
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜbashで関数を定義するのか(背景・原理)
bashの関数は、よく使うコマンドの組み合わせに名前を付けて、ひとつのコマンドのように再利用できる仕組みです。エイリアスでは「コマンドの別名」しか作れませんが、関数なら引数を受け取って処理を分岐させたり、複数行のコマンドをまとめたりできます。
たとえば「特定ディレクトリのシンボリックリンクだけ一覧表示する」「ログから当日分だけ抜き出す」といった日常作業は、関数化することで一発呼び出しが可能になります。
セミナーの受講生にも「ターミナルで同じ操作を3回以上繰り返したら関数化を考える」というルールを伝えています。タイピング量だけでなく、ミスの確率も大幅に減るからです。
関数を定義する基本書式(function構文)
bashで関数を定義する書式は次の2通りで、どちらも有効です。・function 関数名() { コマンド; }
・関数名() { コマンド; }
「{」の直後と「}」の直前には半角スペースが必要で、コマンドの末尾にはセミコロン「;」を付けます。
ここを省略すると「syntax error near unexpected token」のエラーが出るので注意してください。
下記の例では、指定したディレクトリのシンボリックリンクファイルのみをリスト表示する関数 lslink を定義しています。
$ function lslink() { ls -l $1 | grep '^l'; } $ lslink /etc lrwxrwxrwx. 1 root root 11 1月 14 14:22 2014 init.d -> rc.d/init.d lrwxrwxrwx. 1 root root 7 1月 14 14:25 2014 rc -> rc.d/rc lrwxrwxrwx. 1 root root 13 1月 14 14:25 2014 rc.local -> rc.d/rc.local lrwxrwxrwx. 1 root root 10 1月 14 14:25 2014 rc0.d -> rc.d/rc0.d lrwxrwxrwx. 1 root root 10 1月 14 14:25 2014 rc1.d -> rc.d/rc1.d lrwxrwxrwx. 1 root root 10 1月 14 14:25 2014 rc2.d -> rc.d/rc2.d
関数を利用できるのはその関数を定義したシェル内のみで、別のターミナルを開いても引き継がれません。永続化したい場合は後述する「.bashrcに登録する」を参照してください。
関数の引数($1 $2 $@)を受け取って処理する
bashの関数は、シェルスクリプトと同じく位置パラメータで引数を受け取ります。・$1, $2, $3 ... :1番目、2番目、3番目の引数
・$@ :すべての引数を個別にまとめて参照
・$# :引数の個数
・$0 :シェル名(関数では関数名ではないことに注意)
たとえば、引数で渡したファイルの行数だけを表示する関数は次のように書けます。
$ function lc() { wc -l "$1" | awk '{print $1}'; } $ lc /etc/passwd 45
関数の戻り値とreturnの使い方
bash関数からの戻り値は、return 文で0~255の整数を返すか、関数の最後に実行されたコマンドの終了ステータスを返します。「文字列を戻り値にしたい」というケースは、echo の出力をコマンド置換でキャプチャするのが定石です。
$ function add() { echo $(($1 + $2)); } $ result=$(add 3 5) $ echo $result 8
ここを混同するとシェルスクリプト初心者が必ずつまずきます。
関数の確認と削除(declare -f / unset)
現在定義されている関数の一覧と中身を確認したい場合は、declare -f コマンドを使います。$ declare -f lslink () { ls --color=auto -l $1 | grep '^l' }
関数名だけを一覧したい場合は declare -F(大文字F)を使うと、関数名一覧のみが表示されます。
特定の関数の定義内容を確認するなら、関数名を指定します。
$ declare -f lslink lslink () { ls -l $1 | grep '^l' }
bashでは変数名と関数名を区別しないため、名前が重複しないよう注意する必要があります。同じ名前で変数を定義すると関数が呼び出せなくなるケースもあります。
関数定義を削除するには、変数を削除するときと同様に unset コマンドを使用します。下記の例では、関数 lslink を削除しています。
$ unset lslink $ lslink /etc -bash: lslink: コマンドが見つかりません
.bashrc に登録して関数を永続化する
シェルを閉じると関数の定義は消えてしまいます。次回ログイン以降も使い続けるには、ユーザーのホームディレクトリにある .bashrc に関数を追記します。# ~/.bashrc に追記 function lslink() { ls -l "$1" | grep '^l' }
$ source ~/.bashrc
bash関数 早見表
| やりたいこと | コマンド |
|---|---|
| 関数を定義する | function 名前() { 処理; } |
| 関数を定義する(function省略) | 名前() { 処理; } |
| 引数を受け取る | $1 $2 $@ "$1" |
| 関数の終了ステータスを返す | return 0 |
| 関数の文字列を取得する | result=$(関数名 引数) |
| 定義済み関数と中身を一覧 | declare -f |
| 定義済み関数名のみ一覧 | declare -F |
| 特定の関数定義を表示 | declare -f 関数名 |
| 関数を削除する | unset -f 関数名 |
| 関数を永続化する | ~/.bashrc に追記して source ~/.bashrc |
「command not found」が出た時の対処法
関数を定義したつもりなのに「command not found」「コマンドが見つかりません」と出る場合、原因は次の3つが代表的です。・別シェルで定義した:定義はシェルごとなので、ターミナルを開き直すと消える
・スクリプトの中で定義した:子プロセスで定義された関数は親シェルに引き継がれない(source か . で実行する)
・スペル違い・大文字小文字違い:bashは大文字小文字を厳密に区別する
スクリプトを source 経由で読み込めば、定義した関数がそのまま現在のシェルで使えるようになります。
$ source ./myfunc.sh # または $ . ./myfunc.sh
本記事のまとめ
bashの関数を function 構文で定義することで、よく使うコマンドの組み合わせを短い名前で呼び出せます。引数の受け取りや戻り値、declare -f での確認、unset での削除、.bashrc での永続化まで身につければ、日々のターミナル作業は確実に速くなります。
シェルスクリプトを書く前段階として、まずは普段の作業を関数化していくところから始めてみてください。
無料のLinux Master Magazineでは、現場で本当に使われているbashテクニックを定期的に配信しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます