xattr コマンドの使い方／ヘルプの日本語訳（macOS でパーミッションの@付き拡張属性の操作）

> macOS 上で `ls -l` を実行すると、たまにパーミッションに `@` 付きの属性が表示されます。
> 
> これは何ですか？

```shell-session:iCloud_Driveのディレクトリの例
$ ls -l
total 0
drwxr-xr-x@  5 admin  staff  160  7  1  2019 Data_Line
lrwxr-xr-x@  1 admin  staff   22  9  5 10:44 Documents -> /Users/admin/Documents
drwxr-xr-x@ 10 admin  staff  320  9 21 09:24 Setup Files
drwxr-xr-x@  6 admin  staff  192  9 20 06:06 画像
drwxr-xr-x@  4 admin  staff  128  9 21 09:02 フォント
drwxr-xr-x@  8 admin  staff  256  9 21 09:04 ドライバ 
drwxr-xr-x@  6 admin  staff  192  9 21 09:01 ディスクイメージ
#         ↑ これ
```

[「mac 拡張属性 変更」でググって](https://www.google.com/search?q=site:qiita.com+mac+%E6%8B%A1%E5%BC%B5%E5%B1%9E%E6%80%A7+%E5%A4%89%E6%9B%B4)みても、まとまった Qiita 記事がなかったので自分のググラビリティとして。

## "@" は拡張ファイル属性

<font color=darkorange>**パーミッションの `@` は「OS 固有の、特殊なファイル属性」が付加されていることを表す記号**</font>です。一般的に、拡張属性（`Extended Attributes`、略称 `xatt`）と呼ばれます。

- [拡張ファイル属性](https://ja.wikipedia.org/wiki/%E6%8B%A1%E5%BC%B5%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%B1%9E%E6%80%A7) @ Wikipedia

「ファイルの書込み権限」や「タイムスタンプ」と言った一般的なファイルシステムの属性情報だけでなく、OS 独自の属性も紐付けられているという記号です。つまり、**拡張された属性情報を持ったファイルやディレクトリである、と言う意味**になります。

そのため、上記は iCloud Drive 内のファイルなので、macOS の特殊な属性が付いているのは理解できます。

では、どのような属性が付加されているのか、「属性名」を確認するだけであれば `ls -l@` と `@`（アットマーク）付きで `ls` すると確認できます。

以下の例では `/`（ルートディレクトリ）を `ls -l@` すると、いくつかのディレクトリに `com.apple.rootless` と言う拡張属性が値ゼロで付加されているのが確認できます。

```shell-session
$ ls -l@ /
total 9
drwxrwxr-x+ 30 root  admin   960  9 22 09:31 Applications
drwxr-xr-x  64 root  wheel  2048  9 17 22:43 Library
drwxr-xr-x@  8 root  wheel   256  8 11 03:18 System
	com.apple.rootless	   0 
drwxr-xr-x   6 root  admin   192  9  5 15:39 Users
drwxr-xr-x   5 root  wheel   160  9 22 09:38 Volumes
drwxr-xr-x@ 38 root  wheel  1216  8 11 03:39 bin
	com.apple.rootless	   0 
drwxr-xr-x   2 root  wheel    64  6  6 08:55 cores
dr-xr-xr-x   3 root  wheel  4513  9 22 09:36 dev
lrwxr-xr-x@  1 root  admin    11  9  5 10:19 etc -> private/etc
	com.apple.rootless	   0 
lrwxr-xr-x   1 root  wheel    25  9 22 09:37 home -> /System/Volumes/Data/home
drwxr-xr-x   2 root  wheel    64  6  6 09:05 opt
drwxr-xr-x   6 root  wheel   192  8 11 03:20 private
drwxr-xr-x@ 63 root  wheel  2016  9  5 10:25 sbin
	com.apple.rootless	   0 
lrwxr-xr-x@  1 root  admin    11  9  5 10:25 tmp -> private/tmp
	com.apple.rootless	   0 
drwxr-xr-x@ 11 root  wheel   352  9  5 10:25 usr
	com.apple.rootless	   0 
lrwxr-xr-x@  1 root  admin    11  9  5 10:25 var -> private/var
	com.apple.rootless	   0 
```

ちなみに `com.apple.rootless` の<font color="darkorange">**`rootless` 属性とは「[SIP](https://ja.wikipedia.org/wiki/%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E6%95%B4%E5%90%88%E6%80%A7%E4%BF%9D%E8%AD%B7) を無効にしない限り `root` 権限でも削除できないもの」を示しています**</font>。

また、`@` 以外にも `+` の属性もあります。

```shell-session
$ ls -l /Users
total 0
drwxr-x---+  3 Guest   _guest    96  6 17  2023 Guest
drwxrwxrwt  19 root    wheel    608  7 17 19:49 Shared
drwxr-xr-x+ 83 keinos  staff   2656  8 29 20:19 keinos
drwxr-xr-x+ 19 demo    staff    608 12  5  2020 demo
```

`+`（プラス）属性は [ACL](https://ja.wikipedia.org/wiki/%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E5%88%B6%E5%BE%A1%E3%83%AA%E3%82%B9%E3%83%88) 付き（アクセス制限された）ファイル／ディレクトリであるという意味です。


:::note info
**併せて読みたい**
- [KiCad(Mac版)とFreerouting1.4.4(Mac版)を使う前に.appが開けなかった話](https://qiita.com/NNNGriziMan/items/4ca24be4fe508118f893) @ Qiita
- [Macでファイルを選択すると「"xxx”は壊れているため開けません。 ゴミ箱に入れる必要があります。」と出る](https://qiita.com/seigot/items/49b9fe382767bf59604f#_reference-0c4f4f7a570890eb37d6) @ Qiita
- [macOS でよく見かける拡張属性や ACL](https://qiita.com/reo/items/d68b41c807770b6ebb10) @ Qiita
:::

## macOS のファイルの拡張属性を設定／変更／削除する

Linux などでは `setfattr` や `setxattr` コマンドを使って拡張属性を操作できます。しかし、macOS や BSD などの UNIX 系 OS には `setfattr` や `setxattr` コマンドがありません。代わりに `xattr` コマンドを使います。

`xattr` コマンドで、どんな操作ができるか知りたかったので `xattr` コマンドのヘルプを日本語に翻訳してみました。いささか「整ってない感」がありますが、原文自体がゴチャゴチャした言い回しであるため、ご了承ください。🙇

### TL; DR <sub><sup>（今北産業）</sup></sub>

1. 属性の表示： `-l` (list)
1. 属性の付与/書き込み： `-w` (write)
1. 属性の削除： `-d` (delete)

## xattr コマンドの日本語訳ヘルプ

```bash
XATTR(1)                  BSD General Commands Manual                 XATTR(1)

コマンド名
     xattr -- Extended Attributes（拡張属性）の表示と操作を行います。

構文
     基本構文
     xattr [ オプション ] [ フラグ ] [ <属性名> ] [ <属性値> ] <ファイル> ...

     1) xattr [-lrsvx] <ファイル> ...
     2) xattr -p [-lrsvx] <属性名> <ファイル> ...
     3) xattr -w [-rsx] <属性名> <属性値> <ファイル> ...
     4) xattr -d [-rsv] <属性名> <ファイル> ...
     5) xattr -c [-rsv] <ファイル> ...
     6) xattr -h | --help

説明
     xattr コマンドを使用すると、拡張された属性を表示、変更、または削除でき
     ます。1 つ、または複数のファイル／ディレクトリ／シンボリックに対して実
     行できます。

     拡張属性（Extended Attributes）とは、ファイルと共に保存される任意の
     メタデータ（データの管理上、必要な記述情報）ですが、変更時間やファイル
     サイズと言ったファイルシステムの属性とは異なるデータです。

     メタデータは通常 null で終了する UTF-8 の文字列ですが、任意のバイナリ
     データにすることもできます。

     コマンドラインで 1 つ以上のファイルを指定できます。コマンドの構文のうち
     最初の 2 つでは、複数のファイルが指定された場合、ファイル名が結果ととも
     に表示されます。ファイルが1つだけ指定された場合は、通常、ファイル名は表
     示されません。（後ほど説明する -v オプションフラグも指定されている場合
     を除く）。

     コマンドの最初の構文で、他のオプションが指定されていない場合は、すべての
     拡張属性の名前がリスト表示されます。また、属性名を確認するだけの場合は、
     `ls -l@` を使用して表示することもできます。

     ２番目の構文では、-p オプション（"print"）を使用して、指定された属性名
     に関連付けられた値が表示されます。属性値は通常、文字列として表示されます。
     ただし、データで nil が検出された場合、値は16進表記で表示されます。

     3番目の構文は、-w オプション("write")を使用して、指定された属性名に指
     定された値を割り当てます。

     4番目の構文では、-d オプション（"delete"）を使用して、指定された属性名
     および関連する値を削除します。

     5番目の構文では、-c オプション（"clear"）を指定すると関連する値を含む、
     すべての属性が削除されます。

     最後の６番目の構文は、-h または --help オプションを指定すると短いヘルプ
     メッセージを表示し、ただちに終了します。

オプションフラグ
     -l  デフォルトでは、最初の2つのコマンド構文では、それぞれ属性名または属
         性の値のみを表示します。-l オプションフラグにより、属性名とその属性
         の値の両方が表示されます。値に nil が検出された場合は、値は16進数の
         オフセット値が表示され、「`|`」で囲まれた ASCII が続きます。

     -r  引数のファイルがディレクトリの場合、ディレクトリ内の全てのファイルに
         再帰的に適用されます。また、正規表現で複数ファイルも指定できます。
         `xattr -c -r <ディレクトリ>`
         `xattr -c -r *.png`

     -s  引数のファイルがシンボリックリンクの場合、リンク先ではなくシンボリッ
         クリンク自身に作用します。

     -v  引数のファイルが1つであっても、ファイル名を表示させます。

     -x  属性値を強制的に16進表記で表示します。

     -w  指定された属性値の設定値が文字列であると想定します。-x オプションフ
         ラグも指定された場合、入力値は16進表記であると判断されます。ことの時
         スペースは無視されます。`xxd`(1) コマンドを使用して、既存のバイナリ
         データから16進表記の文字列を作成し、xattr に渡すこともできます。

終了ステータス

     xattr コマンドは、成功すると 0（ゼロ）のステータスで終了します。エラーの
     場合、ゼロ以外が返され、エラーメッセージが標準エラー（`STDERR`）に出力さ
     れます。システムコールエラーの場合、エラーコードとエラー文字列の両方が表
     示されます。
     エラーコードの一覧は次のコマンドを参照してください getxattr(2),
     listxattr(2), removexattr(2), setxattr(2)。

     一部の属性は設定値が、システムによって強制的に固定長に制限される場合があ
     ります。
     例）
           % xattr -w com.apple.FinderInfo 0 foo
           xattr: [Errno 34] Result too large: 'foo'

           com.apple.FinderInfo 属性は、長さが32バイトでなければなりませ
           ん。

使用例

     この例では、com.apple.FinderInfo 属性を /usr ディレクトリから MyDir
     ディレクトリにコピーします。

           % xattr -px com.apple.FinderInfo /usr
           00 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00
           00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
           % xattr -l MyDir
           % xattr -wx com.apple.FinderInfo \
             "`xattr -px com.apple.FinderInfo /usr`" MyDir
           % xattr -l MyDir
           com.apple.FinderInfo:
           00000000  00 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00  |........@.......|
           00000010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |................|
           00000020

関連項目
     ls(1), xxd(1), getxattr(2), listxattr(2), removexattr(2), setxattr(2)

BSD                              Nov 29, 2010                              BSD
```