はじめに
Unix系OSで日頃よく使うコマンドは、 .bashrc や .zshrc に alias や function を定義しておき、コマンドラインから呼び出すことだと思います。
僕も .bashrc や .bashrc に自分のお気に入りのエイリアスや関数を定義していますが、この関数を別のシェルスクリプトから呼び出したいというシーンが有りました。
ちょっと工夫をしないと呼び出せなかったこともあり、やり方を掲載したいと思います。
検証環境
| |
まずは .bashrc に関数を定義してみる
まずは自分の .bashrc に関数を定義してみます。
ただ渡された引数を出力するだけの print_params という、関数です。
| |
.bashrc に追加した関数は以下のいずれかの方法で反映できます。
- ログインし直す
bashコマンドを実行し、シェルを新しいプロセスで立ち上げる. ~/.bashrcコマンドを実行し、現在事項中プロセスのシェルに関数を反映させる
今回は3つめの方法で反映させます。
| |
関数が作成されたかどうか確認してみます。
| |
正しく関数が作成されました。 ここからは、作成された関数を他のシェルから呼び出してみます。
.bashrc に定義されている関数は別のシェルスクリプトからは呼び出せない
test.sh というファイルを作成し、先程 .bashrc で定義した関数を呼び出してみます。
| |
このスクリプトを実行してみます。
| |
エラーが発生してしまいました。 print_params というコマンドが見つからない、と言っています。
親シェルプロセスで定義したシェル関数は子シェルプロセスから見えない
「親シェルプロセス」で定義した関数は「子シェルプロセス」から見えません。
Bashの関数は、現在実行中のシェルプロセス内でしか利用することはできません。
./test.sh のように、シェルスクリプトを実行すると、「子シェルプロセス」が自動的に立ち上がり、シェルのロジックが実行されます。
したがって、「親シェルプロセス」で定義した関数 print_params が見えなかったのです。
これを解決する方法はないのでしょうか?
ビルトインコマンド export で関数を公開する
Bashのビルトインコマンド export は、変数を「子シェルプロセス」に 公開 するために利用します。
実は export コマンドを使って、関数も「子シェルプロセス」に 公開 することができます。
先程の ./test.sh を実行する前に関数を公開してみましょう。
| |
この状態で、先程の ./test.sh を実行してみます。
| |
エラーは表示されず、正しく実行できました。
再度ログインしてきた場合にも公開されるようにする
一度ログアウト、あるいは端末を終了し、再度Bashを起動してみましょう。
./test.sh を実行すると、またまた関数が見つからないことによるエラーが発生するかと思います。
毎回ログインするたびに export -f print_params するのは面倒ですので、こちらも ~/.bashrc に記述しておきましょう。
| |
これで、今後はログインした直後に自動的に関数が子プロセスに公開されるようになります。
ちょっとしたコールバック関数を用意してみる
この仕組を利用して、ちょっとしたコールバック関数を用意することもできます。
callback という名前の関数にコマンドライン引数をそのまま引き渡すシェルスクリプトを用意してみます。
| |
この状態では、当然実行するとエラーとなります。
| |
ここで callback という名前の関数を作成、公開してみます。
関数は2つの引数を加算した結果を出力する関数です。
| |
再度先程のスクリプトを実行してみます。
| |
加算結果が返却されました。
今度は減算してみましょう。
| |
一度関数を公開していれば、関数のロジック変更後に再度公開する必要はありません。 スクリプトを実行してみます。
| |
ひとこと
便利そうですが、関数を使わずシェルスクリプトを使えばなんとかなるということもあり、あまり利用するケースは多くないかもしれません。
関数のメリットはシェルスクリプトの読み込みのオーバヘッドが減らせる点でしょうか。
同じロジック( echo 1 するだけ)のシェルスクリプト x.sh と x_func を10000回呼び出した場合の処理速度の違いは以下の通りでした。
| |