拡張子に応じたコマンドを自動実行

zshにはファイル名の拡張子に対応して自動的にコマンドを実行させる機能がある。これは動作例を見るのが一番分かりやすい。たとえばプロンプト1.1のように実行する。テキストファイルの中身を見たいという気持ちは伝わってくるが、当然、テキストファイルなので実行できないとエラーが出力される。

プロンプト1.1 中身を見たいという気持ちは伝わってくるが当然エラー


% ls
COPYRIGHT.txt
% ./COPYRIGHT.txt
zsh: permission denied: ./COPYRIGHT.txt
%

そこで「alias -s txt=cat」を実行する。こうすると拡張子がtxtのファイルが直接実行された場合、「指定されたコマンドで実行する」という処理が行われる。これは実際に使ってみるとかなり便利な機能だ。プロンプト1.2の場合、テキストファイルに対して自動的にcatコマンドが実行されたわけだ。

プロンプト1.2 alias -sを使えば指定したコマンドを自動実行


% alias -s txt=cat
% ./COPYRIGHT.txt
The compilation of software known as FreeBSD is distributed under the
following terms:

Copyright (C) 1992-2007 The FreeBSD Project. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
%

特定のデータを閲覧したり処理したりする場合のメモとしても活用できる。例えばコアファイルを解析して表示させるとか特定の決まりきった作業を行う場合、しばらく使っていないとコマンド名やオプションを忘れてしまう。そんな場合はalias -sで拡張子に処理を対応付け、設定ファイルに書き込んでおくとよい。コマンドを忘れてしまってもファイルを直接指定すれば処理が実行される。

ガガガっと列挙するのもよし

例えば、代表的な拡張子だとリスト2.1のような感じだろう。とにかく、ガガガっとリストしてしまえばよい。いくらでも複雑に処理させることはできるが、実はこうしたシンプルな形が一番使い勝手がよい。

リスト2.1 拡張子にコマンドを対応付ける例


alias -s zip=zipinfo
alias -s tgz=gzcat
alias -s gz=gzcat
alias -s tbz=bzcat
alias -s bz2=bzcat

alias -s java=lv
alias -s c=lv
alias -s h=lv
alias -s C=lv
alias -s cpp=lv
alias -s sh=lv
alias -s txt=lv
alias -s xml=lv

alias -s html=firefox
alias -s xhtml=firefox

alias -s gif=display
alias -s jpg=display
alias -s jpeg=display
alias -s png=display
alias -s bmp=display

alias -s mp3=amarok
alias -s m4a=amarok
alias -s ogg=amarok

alias -s mpg=svlc
alias -s mpeg=svlc
alias -s avi=svlc
alias -s mp4v=svlc

インストールされているアプリケーションを判定したり

このあたりであまり凝ったことをしても最終的な手間はそれほど変わらないと思うが、「どの環境にいっても同じ設定でそのまま動いて欲しいんだよね」という痒いところも対処していくのが紳士道。コマンドにオプションを含めたり条件分岐を入れるなどといったことを行うと面倒なことになるのだが、とりあえずリスト3.1くらいまでなら書いてしまってもよいだろう。

リスト3.1 判定処理を入れてちょっとだけ汎用性を上げてみたり…

for target in java c h C cpp sh txt xml
do
 alias -s ${target}=zsh_pager
done

for target in html xhtml
do
 alias -s ${target}=zsh_wevbbrowser
done

for target in gif jpg jpeg png bmp
do
 alias -s ${target}=zsh_imageviewer
done

for target in mp3 m4a ogg
do
 alias -s ${target}=zsh_audioplayer
done

for target in mpg mpeg avi mp4v
do
 alias -s ${target}=zsh_movieplayer
done

zsh_pager()
{
 $(zsh_commandselector
  "${PAGER} lv less more cat") ${@+"$@"}
}

zsh_wevbbrowser()
{
 $(zsh_commandselector
  "firefox opera konqueror epiphany less") ${@+"$@"}
}

zsh_imageviewer()
{
 $(zsh_commandselector
  "gthumb imageviewer gqview kview eog display") ${@+"$@"}
}

zsh_audioplayer()
{
 $(zsh_commandselector
  "amarok audacious beep-media-player xmms2 xmms noatun") ${@+"$@"}
}

zsh_movieplayer()
{
 $(zsh_commandselector
  "svlc gmplayer totem xine realplay") ${@+"$@"}
}

zsh_commandselector()
{
 for command in $(echo ${1})
  do
   if type "${command}" > /dev/null 2>&1
   then
    echo "${command}"
    break
   fi
  done
}

リスト3.1の処理はこんなところだ。まず実行するコマンドをカスタム関数に指定し、次にカスタム関数内で処理を振り分けるというもの。ここではコマンドがあるかどうかをチェックする関数としてzsh_commandselectorを用意して使い回している。リスト3.1の場合、拡張子が増えてもそれを追加するだけでよく、使いたいコマンドが変わったらそれも追加するだけでよい。

ただ「エディタで置換すれば一発じゃないかと」という読者もいることだろう。まさにその通り!! そのため、このあたりの設定はあまり凝らなくてもよい。気持ちが急いでいると直接ファイルを指定することがある。よくやるファイルについては設定しておくと便利だ。