Cygwin/MSYS2とごみ箱にできる謎のファイルの関係

CygwinやMSYS2を使っていると、ごみ箱に謎のファイルが (場合によっては数百MB以上) できることがあることに気づき、調べてみました。

# ごみ箱の中身をエクスプローラーから確認

Windowsのごみ箱は、各ドライブのルートディレクトリに `$Recycle.bin` というディレクトリが作られ、その下に各ユーザーのディレクトリが、SID (Security Identifier)と同じ名前で作られます。自分のSIDは`whoami /user`コマンドで確かめることができます。

```
C:\>whoami /user

USER INFORMATION
----------------

ユーザー名 SID
========== =============================================
mmm\uuu    S-1-5-21-XXXXXXXXX-YYYYYYYYYY-ZZZZZZZZZZ-WWWW
```

さて、エクスプローラーでごみ箱の中を見てみましょう。
「表示」→「隠しファイル」にチェックを入れて、隠しファイルも見えるようにした上で、`C:\$Recycle.bin`を開いてみます。

<img width="732" alt="recyclebin.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59454/e74493b4-a31a-0b9d-49c5-fc06bfa69d8f.png">

SIDのディレクトリがいくつか作られ、最後に`ごみ箱`とあるのが見えます。
もし、何も表示されない場合は、「表示」→「オプション」をクリックし、「表示」タブを開き、「保護されたオペレーティング システム ファイルを表示しない (推奨)」のチェックを外します。

他のユーザーのごみ箱はSIDが見えますが、自分のごみ箱はエクスプローラーがSIDを`ごみ箱`に変換して表示しており、SIDは表示されません。自分以外にユーザーがいない場合は、`S-1-5-18`と`ごみ箱`のみが表示されているかもしれません。(`S-1-5-18`は`ローカルシステム`アカウントです。)

`ごみ箱`をダブルクリックして、ごみ箱の中を見てみます。

<img width="732" alt="recyclebin-empty.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59454/506d3f3f-7831-a3df-1f7c-1455abbe9b7d.png">

「このフォルダーは空です。」と表示されています。
次に、`C:\$Recycle.bin`に戻って、`ごみ箱`のプロパティを見てみます。

<img width="299" alt="recyclebin-prop.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59454/38e9efa6-d724-169e-c9b0-d5fc3e30c2d5.png">

なぜか、13.5 MBのファイルがあると表示されています。

# ごみ箱の中身をCygwin/MSYS2から確認

Cygwin/MSYS2からごみ箱の中を見てみます。
minttyを開いて、`cd␣`まで入力し、エクスプローラーから`ごみ箱`ディレクトリをminttyのウィンドウにドラッグ&ドロップすると、ごみ箱のディレクトリのフルパスが入力されるので、<kbd>Enter</kbd>を押せばごみ箱のディレクトリに簡単に移ることができます。

<img width="455" alt="recyclebin-mintty-cd.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59454/671d206f-71e4-ca36-b7ef-6ea488c5d79f.png">

`ls -aF`コマンドを実行してファイルの一覧を見てみます。

<img width="510" alt="recyclebin-mintty-ls.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59454/e77f8845-987f-b869-159c-57fdcea7ed55.png">

`.`で始まり、8進数表記されたバイト列があり、その後16進数が並んだ変な名前のファイルが複数あることが確認できます。

この変なバイト列は何でしょうか。確認するために以下のコマンドを実行して、バイト列をテキストファイルに保存してみます。(bash では、`$'\ooo'`という表記で8進数で文字コードを表現できます。`$'\xXX'`であれば16進数表記になります。)

```bash
$ echo $'\355\261\255\355\261\263\355\261\271\355\261\263' > x.txt
```

これをVimで、UTF-8として開いてみます。

<img width="260" alt="recyclebin-gvim.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59454/4c0be51d-c6f4-3408-4d68-23ae6c23cde8.png">

上位8bitが0xDCのコード、すなわち、[ローサロゲート](https://ja.wikipedia.org/wiki/Unicode#%E3%82%B5%E3%83%AD%E3%82%B2%E3%83%BC%E3%83%88%E3%83%9A%E3%82%A2)のコードが並んでいるのが確認できます。
ここから下位8bitだけを取り出してみると、`6d 73 79 73`となり、実は`msys`という文字列であることに気づくでしょう。
`msys`の他にも、`cyg`や`smym`となるパターンがあることが分かっています。このことから、これらのファイルはCygwinやMSYS2に関係ありそうだと分かります。

# 謎のファイルの正体

Linuxでは、開いているファイルであっても(権限さえあれば)削除することができます。一方、Windowsでは、開いているファイルは、移動することはできても削除することはできません。
Cygwin/MSYS2では、Linuxの挙動をWindows上で模倣するため、ファイルを開くときには`FILE_SHARE_DELETE`フラグを指定しておき、開いているファイルを削除しようとしたときには、それをごみ箱に移動するということをやっているようで、この謎のファイルはそのときの一時ファイルです。ただし、`FILE_SHARE_DELETE`フラグを指定しても完全では無く、ファイルをクローズしてもファイルが削除されずに残ってしまう場合があるようです。

参考:

* [c++ - Cygwin: Deleting file when handle is opened - Stack Overflow](https://stackoverflow.com/questions/47690214/cygwin-deleting-file-when-handle-is-opened)
* [Big Sky :: CreateFile で FILE\_SHARE\_DELETE を指定するとどうなるか](https://mattn.kaoriya.net/software/lang/go/20170817113831.htm)

# 謎のファイルを削除する

上記の通り、この謎のファイルは、使用中のファイルをCygwin/MSYS2で削除しようとしたときにできる一時ファイルであり、ファイルを使っているプロセスが残っていなければ削除してしまって構いません。
念のためWindowsを再起動してからminttyを開き、ごみ箱のディレクトリに移ってから、以下のコマンドを実行してください。

```bash
$ ls .$'\355'*	# 余計なファイルがマッチしていないことを確認
$ rm .$'\355'*	# 削除を実行
```