Skip to main content.

ごく些細な Tips 集

Cygwin を利用する上で多少は便利に使えるであろう、ごく些細な Tips を取り揃えています。

任意のフォルダ上で bash を起動する

レジストリに以下のキーを作成すると、エクスプローラ上の任意のフォルダで、 コンテキストメニュー(右クリックで表示されるメニュー)から任意のコマンドを実行することが可能になります。

HKEY_CLASSES_ROOT\Folder\shell\名前
コンテキストメニューに追加する項目の定義。「名前」がメニュー項目名となるが、このキーの値に文字列を格納することによって、メニューに表示する内容を変更可能。
HKEY_CLASSES_ROOT\Folder\shell\名前\command
当該メニュー項目を選択したときに実行されるコマンドの定義。

これを利用すれば、選択したフォルダをカレントディレクトリとして bash や rxvt を起動出来ます。 レジストリの改変には regedit を使うのが一般的ですが、Cygwin 附属の regtool を使ったほうが簡単だと思います。

まず、レジストリの「HKEY_CLASSES_ROOT\Folder\shell」の下に、「Bash\command」というキーを作成します。 以下の例では「\root」を利用していますが、これは regtool で利用可能な、「HKEY_CLASSES_ROOT」の省略記法です。

$ regtool list '\root\Folder\shell'   ← キーの存在を確認する
explore                               ← 「Bash」というキーは存在しない
open
$ regtool.exe add '\root\Folder\shell\Bash'          ← 「Bash」キーの作成
$ regtool.exe add '\root\Folder\shell\Bash\command'  ← 「Bash\command」キーの作成

キーが出来たら、以下のコマンドを実行してキーに値を登録します。 キー名の最後に「\」が必要な点に注意して下さい。 やっていることは単純で、コマンドプロンプト(cmd.exe)の組み込みコマンド start によって Bash を起動しているだけです。start のオプション「/d」は起動するコマンドのカレントディレクトリを指定するものであり。 「%L」には「選択されたディレクトリ」がエクスプローラから渡されるようになっています。

$ regtool -s set '\root\Folder\shell\Bash\command\' \
    'cmd.exe /c start /d "%L" "Born Again Shell" bash --login -i'      ← 値を設定
$ regtool get '\root\Folder\shell\Bash\command\'
cmd.exe /c start /d "%L" "Born Again Shell" bash --login -i   ← 設定値の確認

これでコンテキストメニューに「Bash」が追加されます。一瞬とは言えコマンドプロンプトが開くので、 あまりスマートではありませんが、これよりいい手段が思いつきませんでした。

このままだとメニューには単に「Bash」と表示されることになりますが、 「HKEY_CLASSES_ROOT\Folder\shell\bash」キーに好きな文字列を設定することで、メニューに表示する内容を変更することが出来ます。

$ regtool -s set '\root\Folder\shell\Bash\' 'Run Bash'

また、現在の Cygwin では /etc/profile 中でホームディレクトリへと移動しているので、その部分をコメントアウトする必要があります(でないと、選択したディレクトリではなく、常にホームディレクトリがカレントディレクトリになってしまいます)。

  :
# Make sure we start in home
cd "$HOME"    ← この行をコメントアウトする
  :

bash の代わりに rxvt を開くなら、次のようにします。rxvt のオプションは適宜変更して下さい。

$ regtool.exe add '\root\Folder\shell\Rxvt'
$ regtool.exe add '\root\Folder\shell\Rxvt\command'
$ regtool -s set '\root\Folder\shell\Rxvt\command\' \
    'cmd.exe /c start /d "%L" "Born Again Shell" rxvt -e bash --login -i'

Cygwin で core ファイルを作成する

Cygwin ではプログラムが異常終了すると「実行ファイル名.stackdump」というファイルが作成されますが、 このファイルでは情報が少なすぎて、デバッグを行うには不都合です。

環境変数 CYGWIN を次のように設定すると、「実行ファイル名.core」という名前でコアファイルが作成されるようになります。 この技は Cygwin DLL 1.3.x 時代には正常に動作しなかったのですが、最近の Cygwin DLL でまた使えるようになりました。

CYGWIN=error_start=dumper

作成されたコアファイルは、gdb -c コアファイル名 で解析出来ます。 以下に例を挙げます。

$ cat main.c
int main(void)
{
    int i;
    i = 7 / 0;         ← 0 による除算なので、絶対に異常終了する
}
$ gcc -g main.c        ← 「-g」オプション付きでコンパイルする
main.c: 関数 `main' 内:
main.c:4: 警告: division by zero
$ echo $CYGWIN         ← 環境変数 CYGWIN の設定値を確認
error_start=dumper
$ ./a.exe              ← a.exe を実行
*** starting debugger for pid 1200, tid 2972
$ ls -lh a.exe.core    ← コアファイルを確認
-rw-rw-rw-    1 riue     なし         2.8M Aug 25 00:27 a.exe.core
$ gdb -c a.exe.core
GNU gdb 2003-09-20-cvs (cygwin-special)
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i686-pc-cygwin".

#0  0x0040108d in main () at main.c:4
4           i = 7 / 0; ← 落ちた場所
(gdb)

環境変数 CYGWIN の値 error_start は、Cygwin アプリケーションが異常終了した際に起動するプログラムを指定するためのものです。 プログラムには第一引数としてプロセスのファイル名、第二引数として Windows でのプロセス ID(pid) が引き渡されます。dumper の代わりに「error_start=gdb」 としておけば、異常終了時に gdb を起動させることも出来ます。 error_start で指定するプログラムが Windows の環境変数 PATH に含まれる場所に存在しない場合は、フルパスを Windows のパス形式で指定しなければなりません。

ところで、突然出てきたこの dumper は Cygwin 附属のプログラムで、 任意のプロセスのコアを作成するためのものです。「dumper ファイル名 pid」 (pid は Windows での pid です)を実行すると、当該プロセスのコアが「ファイル名.core」 として作成されます。尤も、コアを作成するとそのプロセスは即死しますので、注意して下さい。

予約されているファイル名(デバイスファイル名)と同名のファイルを削除する

これは Cygwin とは直接関係ないのですが、1.5.10 など一部のバージョンの Cygwin DLL では、Windows の予約済みファイル名(デバイスファイル名)と同名のファイルを作成出来てしまうため、 その対応方法を記しておきます。

MS-DOS / Windows では一部のファイル名が予約済みとされ、利用することが出来ません(*1)。 これらのファイルは UNIX 系 OS の「デバイスファイル」と同様の役割を持っているのですが、 困ったことに絶対パス形式とはなっていないため、事実上全てのディレクトリに存在することと同じです。 また、拡張子を付けたとしても、これらのファイル名と同名のファイルは作成出来ません(例: aux.c)。

デバイスファイル名 役割
CON コンソールへの入出力。UNIX 系 OS での標準入力 / 標準出力 / 標準エラー出力全ての役割を負っています(内部的なファイルハンドルは別のようです)。
AUX システムに接続されているシリアルポート(RS-232-C)のうち、最初のシリアルポートへの入出力。シリアルポートは「補助装置」と位置づけられているため、「AUX」という名前になったようです。「AUX」は、後述する「COM1」と同じです。
PRN プリンタへの出力。実際には、後述する「LPT1」と同義です。
NUL NULL デバイス。UNIX 系 OS の /dev/null と同じ働きをします。
COM1 〜 COM9 シリアルポートへの入出力(昔は COM4 までだったようです)。「COM」とは「Communication port(通信ポート)」の意味です。
LPT1 〜 LPT9 パラレルポートへの入出力(昔は LPT4 までだったようです)。LPT とは「Line Printer」の意味です。

通常、これらと同じ名前のファイルを作成することは出来ませんが、万が一作成してしまうと、 単純な方法では削除することさえ出来ません。 このような場合は、次のような予約語チェックを避けるための特別な記法を利用して、 削除対象のファイルを指定する必要があります。

\\.\ドライブレター:\パス\ファイル名

この記法は Cygwin のツールからは利用出来ませんので、Windows 附属の del コマンドなどを利用します。 例えば、C:\Cygwin\tmp\aux というファイルを削除するには、 コマンドプロンプトから以下のように実行します。

del \\.\C:\Cygwin\tmp\aux

Windows の del コマンドはファイル用ですので、対象がディレクトリの場合は rmdir(又は rd)を利用します。

rd \\.\C:\Cygwin\tmp\nul

*1: MS-DOS では他にも「CLOCK$」(システムクロック)、「CONFIG$」(用途不明)の二つのデバイスが存在したようですが、Windows には存在しないようです。Cygwin のソースコード中(path.ccspecial_name 関数)でも、これらを避けるための処理は行われていません。