LoginSignup
14
15

More than 5 years have passed since last update.

MSYS2でfishを使う

Last updated at Posted at 2015-10-04

msys2 には fish shell のパッケージが用意されています。
bash からプロンプトで fish --login するだけなら簡単ですが、起動時のログインシェルとして使用するためにはいろいろ注意点がありましたのでまとめます。

1. fish のインストール

何はともあれ、pacman を利用して fish をインストールします。
fishは内部で暗黙的にman(nroff)bc を利用するので、これもあわせてインストールしておきます。

pacman -S fish man bc

2. /usr/etc/fish/config.fish の編集

fish をログインシェルとして利用する場合を考えると、bash であれば /etc/profile で設定されているはずの /usr/bin 等のパスが設定されていないため、msys2_shell.bat 等で単純に bash の部分を fish に書き換えて起動しようとすると大量のエラーを見るはめになります。

まずは、 /etc/profile での指定に相当する設定を /usr/etc/fish/config.fish に記述します。
同ファイルの、 if status --is-login (ログインシェルとして起動)の条件内に以下のコードを追加します。

Windows の既存のパスを引き継ぎたくない場合は、1行目末尾の $PATH は抜いておいてもよいです(そのほうがパスが混じらなくてよいような気もする)。

    set PATH /usr/local/bin /usr/bin /bin $PATH
    set MANPATH /usr/local/man /usr/share/fish/man /usr/share/man /usr/man /share/man $MANPATH
    set -gx INFOPATH /usr/local/info /usr/share/info /usr/info /share/info $INFOPATH
    if test -n $MSYSTEM
        switch $MSYSTEM
            case MINGW32
                set MINGW_MOUNT_POINT /mingw32
                set -gx PATH $MINGW_MOUNT_POINT/bin $MSYS2_PATH $PATH
                set -gx PKG_CONFIG_PATH $MINGW_MOUNT_POINT/lib/pkgconfig $MINGW_MOUNT_POINT/share/pkgconfig
                set ACLOCAL_PATH $MINGW_MOUNT_POINT/share/aclocal /usr/share/aclocal
                set -gx MANPATH $MINGW_MOUNT_POINT/share/man $MANPATH
            case MINGW64
                set MINGW_MOUNT_POINT /mingw64
                set -gx PATH $MINGW_MOUNT_POINT/bin $MSYS2_PATH $PATH
                set -gx PKG_CONFIG_PATH $MINGW_MOUNT_POINT/lib/pkgconfig $MINGW_MOUNT_POINT/share/pkgconfig
                set ACLOCAL_PATH $MINGW_MOUNT_POINT/share/aclocal /usr/share/aclocal
                set -gx MANPATH $MINGW_MOUNT_POINT/share/man $MANPATH
            case MSYS
                set -gx PATH $MSYS2_PATH /opt/bin:$PATH
                set -gx PKG_CONFIG_PATH /usr/lib/pkgconfig /usr/share/pkgconfig /lib/pkgconfig
                set -gx MANPATH $MANPATH
            case '*'
                set -gx PATH $MSYS2_PATH $PATH
                set -gx MANPATH $MANPATH
        end
    end

    set -gx SYSCONFDIR /etc

    set ORIGINAL_TMP $TMP
    set ORIGINAL_TEMP $TEMP
    set -e TMP
    set -e TEMP
    set -gx tmp (cygpath -w $ORIGINAL_TMP 2> /dev/null)
    set -gx temp (cygpath -w $ORIGINAL_TEMP 2> /dev/null)
    set -gx TMP /tmp
    set -gx TEMP /tmp

    set p "/proc/registry/HKEY_CURRENT_USER/Software/Microsoft/Windows NT/CurrentVersion/Windows/Device"
    if test -e $p
        read PRINTER < $p
        set -gx PRINTER (echo $PRINTER | sed -e 's/,.*$//g')
    end
    set -e p

    if test -n $ACLOCAL_PATH
        set -gx ACLOCAL_PATH $ACLOCAL_PATH
    end

    set -gx LC_COLLATE C
    for postinst in /etc/post-install/*.post
        if test -e $postinst
            sh -c $postinst
        end
    end

2-2 パスに (x86) が含まれているとき、<TAB> 補完に失敗する件への対応

complete.cpp does not parse PATH directories with parenthesis correctly. #952 fish-shell/fish-shell

64bit Windows の場合、$PATH(x86)が含まれています。
この環境で msys2 上の fish のプロンプトで<TAB>キーでコマンドの補完をした時、 fishは$PATH中の (x86) をコマンド実行の置換のための (...) の構文と解釈して、x86 というコマンドを実行しようとしてしまい、結果 <TAB> 補完中にエラーが出力される、という現象が発生します。。

そこで、上記 /usr/etc/fish/config.fish に、以下の function を定義します。

    function x86
        echo '(x86)'
    end
    function X86
        echo '(X86)'
    end

(x86) がコマンドとして解釈された場合に "(x86)" を返すという、たいへんバカバカしい Workaround ですが、ちゃんと動きます。

3. c:/msys64/msys2_shell.bat を編集

ここまでやったら、スタートメニューのMSYS2 shell.batから fish が起動するように変更します。

start %WD%mintty -i /msys2.ico /usr/bin/bash --login %*

のところを

SET XDG_RUNTIME_DIR=/tmp/fish.%USERNAME%
start %WD%mintty -i /msys2.ico /usr/bin/fish --login %*

に変更します。

XDG_RUNTIME_DIR を変更しているのは、msys2 や cygwin ではこの変数がシェル起動時に自動的に設定できないようで、手動で指定しない場合に、エラーとなってしまうためです。
(https://github.com/fish-shell/fish-shell/issues/1887#issuecomment-70234859)

4. ConEmu からの起動

さらにおまけで、ConEmu でも利用したい場合は、以下のような Task を追加して、以下のようなコマンドを指定します。

C:\msys64\usr\bin\sh.exe -c 'LANG=C.UTF-8 MSYSTEM=MSYS XDG_RUNTIME_DIR=/tmp/fish.$USERNAME exec /usr/bin/fish --login' -new_console:C:"\msys64\msys2.ico" -new_console:d:"%USERPROFILE%"

$LANG が Windows の指定と異なる場合もあるので、その場合は指定しておきます。
特に、Windowsでの環境変数 $LANG に文字コードを含めないロケールを指定している場合、コマンドプロンプト等に記号を出すような場合(oh-my-fishとか入れたいですよね?)にエラーが表示されることがあります。

ただ、ConEmu上でのfishの挙動はちょっと怪しい感じで、fish自体が突然落ちたり、右プロンプトを指定していると文字入力の度に改行されてしまったりするため、あまりオススメしないです。素直にmintty上で使うのがよさげ。

14
15
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
15