-rw-r--r--@って? Mac OSXのExtended Attributesを除去する

謎の@

% ls -l
-rw-r--r--+  1 user  admin   2688 Sep 24 21:02 File1.php
-rw-r--r--+  1 user  admin   3136 Sep 28 15:01 File2.php
-rw-r--r--@  1 user  admin   2526 Oct  7 09:09 File3.php
-rw-r--r--+  1 user  admin  20365 Oct  7 19:51 File4.php

パーミッションの後ろに@がついているファイルがあります。

今回はMac OSX Serverで構成されたリモート上での出来事なのですが、このファイルは公開ディレクトリ内のファイルです。同じファイルをFTP ( キャプチャで使用しているのはTransmit )を通して見ると、MacBinary archiveとして確認され、.binが付与されています

確認すると、リモート先のMax OSX Server上でmiを使って編集されたファイルと判明。これをローカルに落として編集しようとすると、うまく取り扱えずにハマります。今回はこの現象の原因とか解決法の逐次的メモです。

バイナリファイル?



元はもちろんphpが書かれたテキストファイルです。このファイルをダウンロードして、無理矢理テキストエディタで開けてみると、本来の内容の上下を囲うように変なバイナリとテキストの混合データが加わっていることが確認できました。

Extended Attributes というものらしい。

このデータが何なのかについては、【コラム】OS X ハッキング! (253) Leopard解体新書(4) 〜拡張された拡張属性〜 に答えがありました。

EAは、メタデータと総称されるファイル付加情報の1つ。ファイル名とパーミッション、ファイル作成日を除くさまざまな情報が記録され、 Spotlightによる検索などに用いられる。そもそもHFS Plusは、データフォークとリソースフォーク以外のフォークを確保できるよう設計されていたが、実際には利用されてこなかった。EAが実装されたことにより、ユーザやアプリケーションが自由に、ファイルの本質とは直接関係のない修飾的な情報を保存できるようになったのだ。

記事に従ってリモートから見てみよう

Leopardのlsコマンドは、@オプションで、EAもリストアップできるらしいので 、リモートでls -l@を実行するとこんな感じ。他はついていませんが、@がついたファイルのみEAが表示されています。

% ls -l@
-rw-r--r--+ 1 user  admin   2688 Sep 24 21:02 File1.php
-rw-r--r--+ 1 user  admin   3136 Sep 28 15:01 File2.php
-rw-r--r--@ 1 user  admin   2526 Oct  7 09:09 File3.php
    com.apple.FinderInfo       32 
    com.apple.ResourceFork   2843 
    com.apple.TextEncoding     15 
-rw-r--r--+ 1 user  admin  20365 Oct  7 19:51 File4.php

ローカルに落として確認

次にローカルにダウンロードした .bin 状態のものも確認します。

% ls -l@
-rw-r--r--@ 1 user  staff   2688 10  8 10:21 File1.php
    com.apple.metadata:kMDItemWhereFroms      113 
-rw-r--r--@ 1 user  staff   3136 10  8 10:21 File2.php
    com.apple.metadata:kMDItemWhereFroms      112 
-rw-r--r--@ 1 user  staff   5632 10  8 10:21 File3.php.bin
    com.apple.metadata:kMDItemWhereFroms      116 
-rw-r--r--@ 1 user  staff  20365 10  8 10:21 File4.php
    com.apple.metadata:kMDItemWhereFroms      111 

すでに変質しています。kMDItemWhereFromsというメタデータが付与されていますが、名前からして恐らくダウンロード元の情報でも格納されているのでしょう。

% xattr -l File3.php.bin
00000000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |bplist00.._.Aftp|
00000010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |://abcde.example|
00000020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |.com//ab/cde/fgh|
00000030  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |i/jkl/mnopq/rstu|
00000040  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |vwx/File3.php...|
00000050  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |................|
00000060  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |...............N|
00000070

バイナリ部分は隠蔽しています。案の定、ダウンロード元のFTPアドレスが記録されていました。他の正常に開けるファイルにも付いているので、これはダウンロード時にTransmitあたりが自動で付与していると見て間違いないはず。

解決法と仮説

まずはさっくりと解決法からいきます。

xattr -d でEAを除去する

ようはxattrを削り取れば良さそうなので、消しまくります。Xattr にドキュメントとおぼしきものがあったのでこれを参考にして実行します。

-d Delete an existing extended attribute from all of the file objects.

% xattr -d com.apple.FinderInfo File3.php
% xattr -d com.apple.ResourceFork File3.php
% xattr -d com.apple.TextEncoding File3.php

ResourceForkまで消していいのかな、と不安でしたが容赦なく消してOKです。こうしてEAを全部取り去ってやると、FTPからみても正常にファイルが表示されるようになりました。

今回の現象の仮説

そもそもEA自体は悪者ではなく、ローカルMacのファイルにはいずれにも付与されているデータです。ただし、今回のEAの中身はMacで利用するためのメタデータなので、FTP等で他とファイルをやり取りする際には除去されるべきデータでしょう。そのため、FTP等でアップロードする時には、xattrを除去する処理がアプリケーションのどこかで実装されているはず。

それが今回は、リモート先のMac OSX Serverで直接編集されることで、バイナリが混じったxattrがついたまま保存されたことによって、FTPクライアントがファイルを正常に認識できなかったものと思われます。

diskutil info / で確認したところ、ファイルシステムは、リモートもローカルも同じだったので、ファイルシステム的な問題ではなく、そもそもFTPクライアントがxattrを取り扱えない(?)のが原因かな、という所です。

※FTPクライアントは、Transmit、Dreamweaver、CyberDuckのいずれでも同様の現象が確認できていたようです。