Nukino's memorandum

とあるソフト屋の覚え書き

Cygwin(mintty)のシェル設定ファイル読み込み順

cygwin+minttyで

C:\cygwin\bin\mintty.exe -i /Cygwin-Terminal.ico -

とした場合と

C:\cygwin\bin\mintty.exe -i /Cygwin-Terminal.ico

とした場合(“-“(ハイフン)の有無)で挙動が違う(読み込まれる設定ファイルが違う&起動速度が違う)ので調べてみた。

設定ファイルの読み込み順

挙動の違いはman minttyとすれば記述がある。

SYNOPSIS
mintty [OPTION]… [ - | PROGRAM [ARG]… ]
~~~中略~~~
INVOCATION
If a program name is supplied on the command line, this is executed with any additional arguments given. Otherwise, mintty looks for a shell to execute in the SHELL environment variable. If that is not set, it reads the user’s default shell setting from /etc/passwd. As a last resort, it falls back to /bin/sh. If a single dash is specified instead of a program name, the shell is invoked as a login shell.

引数に”-“(ハイフン)を指定した場合→ログインシェルを起動する。

つまり、

/etc/profile
~/.bash_profile

の順で読み込まれる(ログインシェルをbashにしてる場合??)

但しデフォルトで生成される設定ファイルは
/etc/profile内で/etc/bash.bashrc
~/.bash_profile内で~/.bash_profile
が読み込まれる(source)ので、実際には

/etc/profile
/etc/bash.bashrc
~/.bash_profile
~/.bashrc

の順で読み込まれるということになる。

細かいことを言うと、ホームディレクトリ内の設定ファイルの検索順は http://www.atmarkit.co.jp/flinux/rensai/theory09/theory09b.htmlによると

~/.bash_profile~/.bash_login~/.profile
(ファイルが見つかった時点でそのファイルが読み込まれる)

となっているらしい。cygwinでは最初に~/.bash_profileが生成されるので(~/.profileも生成されるけ ど)、上記のような読み込み順となる。

引数に何も指定しない場合→SHELL環境変数が参照される

Windows側のSHELL環境変数(システム優先)に/bin/bashと指定してある場合、bashが起動するので

/etc/bash.bashrc
~/.bashrc

の順で読み込まれる。

Windows側のSHELL環境変数を指定しなかった場合は/etc/passwdを参照し、それでもシェルが不明なら /bin/shが起動する(Cygwinのログインシェル決定ルーチンもこんな感じぽい)

ログインシェル起動したときに遅い

私の環境では引数に”-“を指定した場合、起動が若干遅い。

各読込ファイルの先頭と~/.bashrcのみ末尾にもdate %T.%Nを追加して、調べてみると

引数に”-“を指定した場合 3214ms
引数に何も指定しない場合 390ms

となってる(コマンド出力のオーバーヘッドがあるため、実際はもう少し速いと思う)
なお環境はWindows7 SP1+Thinkpad T61p[Core 2 duo T9500]。

何故遅いか

何故遅いのか調べてみると/etc/profileのシェルスクリプト読込(source)処理が以下のようになってるみたい

/etc/profile
    /etc/profile.d/*.sh読込・・・
        /etc/profile.d/bash_completion.sh
            /etc/bash_completion
                /etc/bash_completion.d/*読込(*.bak、*.swpなどは除外される)
        /etc/profile.d/lang.sh
        /etc/profile.d/openssl.sh

このうち/etc/profile.d/bash_completion.shが遅そう1なので、cygwin上で

cd /etc/profile.d
mv bash_completion.sh bash_completion.sh.del

としてみたらかなり速くなった(1062ms)。

ただしこの場合bash_completionは使えない。

bash_completionを高速化(必要コマンドのみ使用)

bash_completionはあると結構便利な場合もある(manコマンドの時など)ので、高速化できないかを考えてみ る。

/etc/bash_completion.dの中を見てみると、インストールされてないコマンド(dpkgなど)の補完ファイル がある(/etc/bash_completionではコマンドが実行可能かどうかは調べてないっぽい。まあ実行可能かどうか 調べるのと、読み込むのとどちらが速いかは微妙なところではあるけど。)ので、

mv /etc/bash_completion.d /etc/bash_completion.d.bak
mkdir /etc/bash_completion.d

として、必要な補完ファイルのみを/etc/bash_completion.dにコピーする(この場合、 /etc/profile.d/bash_completion.shの名前は変えない)。

/etcディレクトリをいじくりまわしたくない場合は、~/cygwin/bash_completion.dというディレクトリ を作って、以下を~/.bashrcに書く(この場合、/etc/profile.d/bash_completion.shの拡張子を適当に変え ておく。/etc/bash_completion.dの名前は変えなくていい)

bash-biiltins,gcc,gdb,make,man,shコマンド補完ファイルのみをコピーしたところ最初に比べ ると、かなり速くなった(1810ms)。

ただ、~/.bashrcを書き換える方法だと引数に何も指定しない場合でもbash_completionが有効になってしま うので、それが嫌な場合は~/.bash_profileに移動しとく。

bash_completionを更に高速化(コマンド以外の補完機能オフ)

/etc/bash_completionの読込自体が結構遅い。そこで、bash_completionのコ マンド補完のみ使用するため、/etc/bash_completionの192行目~1201行目(bash_completion ver 1.3の場 合。# start of section containing completion functions called by other functions# start of section containing completion functions for external programsの直前まで)をコピーし、 ~/cygwin/bash_completionというファイルを作って貼り付けておく

んで、~/.bashrcに以下を追加する。

先ほどと同様にbash-biiltins,gcc,gdb,make,man,shコマンド補完ファイルのみを ~/cygwin/bash_completion.dにコピーしたところ、更に速くなった(1320ms)。

manコマンドの補完が効くのは確認したが、他は確認してない。他の記述も引っ張ってこないときちんと動かな かったりするかも。

この方法だと、bash_completionのフル機能が使いたい場合はsource /etc/bash_completionとコマンド を打てばいいと思う(またはエイリアスを設定して、それを打つとか)

まとめ

引数に”-“を指定した場合、実行時間は以下のようになる。機能を限定していくほど高速化する(当たり前だけ ど)

項目 時間
bash_completionフル使用(初期状態) 3214ms
必要コマンドのみ使用 1810ms
コマンド以外の補完機能オフ 1320ms
bash_completoinオフ 1062ms

bash_completionが遅いのは、補完機能をスクリプトで実現しようとしているためだと思う。 他のシェルに切り替えるとこんな涙ぐましいコトしなくてもスマートで高速なのかも知れない。


  1. bash_completionはデフォルトでは入っていない。そういえばgit-completionを入れてから遅くなったような気がするので、この時にbash_completionがインストールされたのだと思う。

Comments