Aliasの相互変換

複数のシェルを使い分けようとすると、どうしても設定ファイルに記述が重複してきます。
一回セットしたら後は変えないようなものなら良いのですが、ちょこちょこ弄るようなエイリアスとか環境変数とか、そんなのは出来れば一つのファイルで管理したい。
ということで、今日は「alias」の「相互変換」のお話です。

私の$HOMEには「.〜.aliases.common」というファイルが4種類あります。

  • .sh.aliases.common (sh/bash/ksh/zsh等用)
  • .csh.aliases.common (csh/tcsh用)
  • .fish.aliases.common (fish用)
  • .rc.aliases.common (rc用)

これらをシェルの起動時に読み込んでいるのですが、数十行のalias定義を全てに書いて置くのではなく、ログイン時に他のシェル用の「.〜.aliases.common」ファイルを変換生成させています。
例えば、「bash」で起動した場合、自分自身は「.sh.aliases.common」を読みますが、ついでに他の3種類に変換して書き込んでおく、というもの。

「.sh.aliases.common」が以下の記述だったとします。

alias c='clear'
alias h='history'
alias julia='/opt/julia-ba9eb0a653/julia'
alias pcsv='/opt/csv8.4/bin/ta6osx/scheme -b /opt/csv8.4/boot/ta6osx/petite.boot'
alias s='/usr/local/bin/shtool'
alias vim='Vim'

これが「.csh.aliases.common」では、

alias c 'clear'
alias h 'history'
alias julia '/opt/julia-ba9eb0a653/julia'
alias pcsv '/opt/csv8.4/bin/ta6osx/scheme -b /opt/csv8.4/boot/ta6osx/petite.boot'
alias s '/usr/local/bin/shtool'
alias vim 'Vim'

こうなれば良いわけです。
「.fish.aliases.common」なら、

function c; clear $argv; end
function h; history $argv; end
function julia; /opt/julia-ba9eb0a653/julia $argv; end
function pcsv; /opt/csv8.4/bin/ta6osx/scheme -b /opt/csv8.4/boot/ta6osx/petite.boot $argv; end
function s; /usr/local/bin/shtool $argv; end
function vim; Vim $argv; end

こう、「.rc.aliases.common」なら、

fn c { clear $* }
fn h { history $* }
fn julia { /opt/julia-ba9eb0a653/julia $* }
fn pcsv { /opt/csv8.4/bin/ta6osx/scheme -b /opt/csv8.4/boot/ta6osx/petite.boot $* }
fn s { /usr/local/bin/shtool $* }
fn vim { Vim $* }

こう、という具合。
変換そのものは、本当にログイン時に一回だけすればいいだけですので、私のところの「bash/zsh/ksh等」が読んでいる「.profile」で、以下のような記述をしています。

# Convert aliases for CSH/FISH/RC
if [ -f ~/.sh.aliases.common ]; then

    # for CSH
    :> ~/.csh.aliases.common
    sed /='/s// '/ < ~/.sh.aliases.common >> ~/.csh.aliases.common

    # for FISH
    :> ~/.fish.aliases.common
    sed -e "/alias/s//function/" -e "/=\'/s//; /" -e "/\'$/s// \$argv; end/" \
    < ~/.sh.aliases.common >> ~/.fish.aliases.common

    # for RC
    :> ~/.rc.aliases.common
    sed -e "/alias/s//fn/" -e "/=\'/s// \{ /" -e "/\'$/s// \$\* \}/" -e /\"/s//\'/g \
    < ~/.sh.aliases.common >> ~/.rc.aliases.common

fi

:>」というのは、空のファイルを作るおまじないで、「sh系」「csh系」で使えます。
「fish」と「rc」の場合は「:>」が使えませんから、「echo -n >」を使います。

空のファイルを作ったら、後は1行ずつ読みながら、「sed」で文字列変換して追加書き込みをしていくだけです。
(ちょっとエスケープが面倒ですけど・・・)

これを「csh/tcsh」の「.login」に書くと、

# Convert aliases for BASH/ZSH/KSH/MKSH/FISH/RC
if (-r "$home/.csh.aliases.common") then

    # for BASH/ZSH/KSH/MKSH
    :> $home/.sh.aliases.common
    sed "/ '/s//='/" < $home/.csh.aliases.common >> $home/.sh.aliases.common

    # for FISH
    :> $home/.fish.aliases.common
    sed -e "/alias/s//function/" -e "/ \'/s//; /" -e /\'\$/s//' $argv; end'/ \
    < $home/.csh.aliases.common >> $home/.fish.aliases.common

    # for RC
    :> $home/.rc.aliases.common
    sed -e "/alias/s//fn/" -e "/\'/s//\{ /" -e /\'\$/s//' $* }'/ -e /\"/s//\'/g \
    < $home/.csh.aliases.common >> $home/.rc.aliases.common

endif

こんな感じになります。
ついでに、「fish」の「config.fish」では、

# Convert aliases for BASH/ZSH/KSH/MKSH/CSH/RC
if test -f ~/.fish.aliases.common

    # for BASH/ZSH/KSH/MKSH
    echo -n > ~/.sh.aliases.common
    sed -e "/function/s//alias/" -e "/\; /s//=\'/" -e "/ \$argv\; end/s//\'/" < ~/.fish.aliases.common >> ~/.sh.aliases.common

    # for CSH
    echo -n > ~/.csh.aliases.common
    sed -e "/function/s//alias/" -e "/\; /s// \'/" -e "/ \$argv\; end/s//\'/" < ~/.fish.aliases.common >> ~/.csh.aliases.common

    # for RC
    echo -n > ~/.rc.aliases.common
    sed -e "/function/s//fn/" -e "/\;/s// \{/" -e "/ \$argv\; end/s// \$\* \}/" -e /\"/s//\'/g < ~/.fish.aliases.common >> ~/.rc.aliases.common

 end

おまけで「rc」の「.rcrc」では、

# Convert aliases for BASH/ZSH/KSH/MKSH/CSH/RC
if (test -e $HOME/.rc.aliases.common) {

    # for BASH/ZSH/KSH/MKSH
    echo -n > $HOME/.sh.aliases.common
    sed -e s/''''/"/g -e s/fn/alias/ -e s/' { '/'='''/ -e s/' \$\* }'/''''/ \
    < $HOME/.rc.aliases.common >> $HOME/.sh.aliases.common

    # for CSH
    echo -n > $HOME/.csh.aliases.common
    sed -e s/''''/"/g -e s/fn/alias/ -e s/'{ '/''''/ -e s/' \$\* }'/''''/ \
    < $HOME/.rc.aliases.common >> $HOME/.csh.aliases.common

    # for FISH
    echo -n > $home/.fish.aliases.common
    sed -e s/''''/"/g -e s/fn/function/ -e s/' {'/';'/ -e s/'\$\* }'/'$argv; end'/ \
    < $HOME/.rc.aliases.common >> $HOME/.fish.aliases.common

}

以上です。

目的はみんな同じなので、見事にクルクル廻ります。
ま、何やってんだろうって感じではありますけどねぇ〜

 

コメントをどうぞ