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
がインストールされたのだと思う。↩