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が遅いのは、補完機能をスクリプトで実現しようとしているためだと思う。
他のシェルに切り替えるとこんな涙ぐましいコトしなくてもスマートで高速なのかも知れない。
-
bash_completionはデフォルトでは入っていない。そういえばgit-completionを入れてから遅くなったような気がするので、この時にbash_completionがインストールされたのだと思う。↩