デフォルトのシェルが「tcsh」から「bash」に変更されたのは、2003年10月リリースのOS X Panther(v10.3)のとき。当コラムの前身第69回(リンク)でも触れているが、NEXTSTEP/OPENSTEPから連綿とCシェルだったものがいきなりBシェルに変更されたため、少々面食らった記憶がある。

昔話になってしまうが、2003年といえばLAMP(Linux、Apache、MySQL、PHP/Perl/Python)という言葉が定着しはじめたばかり。WEB開発プラットフォームとしてのMacの存在感は希薄で、後にMAMP(Linuxの代替としてMacを使用)と呼ばれるほどの勢いを得ると確信していた人はごく少数だろう。当時Appleはラックマウントサーバ「Xserve」を展開していたこともあり、同じくbashを使うLinuxを意識していたのかもしれない。

今回のお題「ユーザ定義関数」は、そのCシェルからBシェルへの変更におけるベネフィットのひとつだ。Bシェルは関数を定義することで機能を拡張できるが、Cシェルにそれはない。システム起動用のスクリプトはともかく、対話形式で作業を進めるTerminalでユーザ定義関数を使えるかどうかはカスタマイズ性を大きく変える。ここではmacOS独自のコマンドを使いつつ、その作例をいくつか紹介してみよう。

Terminalから「ググる」

bashでユーザ定義関数を作成するときの書式は、以下に示すとおり。これを「.bashrc」などの起動時に参照されるファイルに記述しておけばいい。書式は他にもあるが(たとえば「function」は省略できる)、混乱を防ぐためもっともオーソドックスなものを挙げておく。

function 関数名 () {
  コマンド
}

このユーザ定義関数にもっともハマりやすいMac独自のコマンドは「open」だ。引数にファイルやURLをとることができるほか、アプリケーションの起動(-a)、テキストエディタの起動(-e)などオプションも豊富だ。以下の要領でユーザ定義関数に検索エンジンのURLを指定し、そこに(bashから引き継がれる)引数をあてがえば、デフォルトのWEBブラウザで検索できるオリジナル関数ができあがる。

これをホームディレクトリ直下の「.bashrc」(~/.bashrc)などに保存し、シェルを再起動すれば「ggl」が使えるようになる。関数といっても、シェルのビルトインコマンドとして利用できるので、一般的なコマンドやエイリアスと使い勝手は変わらない。

function ggl() {
    open "https://www.google.co.jp/search?q=$1"
}

ただし、このままでは複数のキーワードで検索できないため実用性は低い。以下の作例では末尾を少し工夫し、引数に含まれる半角スペースを「%20」に置き換えることで、複数キーワードによる検索を可能にしている。もちろん漢字/かなも利用できるので、試してみよう。

function ggl() {
    open "https://www.google.co.jp/search?q=${*// /%20}"
}

ユーザ定義関数「ggl」にキーワードを与えて実行すると、デフォルトのブラウザ(Safari)に遷移しGoogleを利用したWEB検索が始まる

どうせならYahoo! JAPANのリアルタイム検索を

これでコツは掴んだだろうか? 以下にYahoo! JAPANのリアルタイム検索用関数も用意したので、あわせて試してほしい。直接Safariを操作する場合、リアルタイム検索はYahoo! 独自の検索フィールドにカーソルを移動しなければならないため思考にタイムラグが生じるが、使い慣れたTerminalから実行すればスムーズそのものということを実感できることだろう。

function yahl() {
    open "https://search.yahoo.co.jp/realtime/search?ei=UTF-8&p=${*// /%20}"
}

Yahoo! JAPANのリアルタイム検索もTerminalから実行できる

カレンダーにイベントを登録

openコマンドばかりでは芸がないので、AppleScriptのCUIフロントエンド「osascript」の活用事例も紹介しておきたい。

以下に示す「event」関数では、引数に与えた文字列でカレンダーアプリのイベントを作成する。日時を指定するとなると、フォーマット(○○年○月○日 ○○時……)どおりに入力/整形せねばならず、作例としては複雑なものになるため、関数実行時の日時を開始時刻として決め打ちしている。会議や打ち合わせの用事が決まったとき、とりあえずカレンダーにイベントだけ登録しておき後で調整するという使用イメージだ。

function event() {
    osascript -e 'on run argv' -e 'tell application "Calendar" to make new event at end of calendar "ホーム" with properties {start date:current date, summary:item 1 of argv}' -e 'end run' $1
}

シェル(関数)からosascriptコマンドに引数を渡すには、最初に「on run argv」を実行し「argv」に引数を入れ、あとで第1引数(item 1 of argv)として取り出せばいい。ここさえ押さえておけば、他のアプリケーションにも流用できることだろう。

引数に与えた文字列がイベント名となる

Macのカレンダーに登録すれば、iCloudを通じてiPhoneのカレンダーにもすぐに同期される。iPhoneで手入力するより断然速い