Mac から Linux サーバへ rsync でファイルを送ったら、日本語ファイル名の濁点・半濁点が分離して「テ゛ータ」のようになった。検索やタブ補完でファイル名がヒットしない。同期し直すたびに全ファイルが再転送される。こうした症状は、文字コードそのものではなく Unicode の正規化形式(NFC/NFD)の違いが原因です。
結論から言うと、Mac 側の rsync に --iconv オプションを付けて、転送時にファイル名を変換するのが定番の解決策です。
# Mac から Linux へ(push でも pull でもこの指定でOK) rsync -a --iconv=utf-8-mac,utf-8 ~/data/ user@linux-server:/path/to/data/
ただし macOS に最初から入っている /usr/bin/rsync ではこのオプションが使えません(後述)。Homebrew で本家 rsync を入れてから実行してください。
brew install rsync
何が起きているのか:NFC と NFD
「デ」という1文字は、Unicode では2通りの表現ができます。
- NFC(合成形): 「デ」1文字。バイト列は
E3 83 87 - NFD(分解形): 「テ」+「結合濁点」の2文字。バイト列は
E3 83 86+E3 82 99
見た目はどちらも「デ」ですが、バイト列としては別物です。Linux では NFC でファイル名を付けるのが普通なのに対し、Mac は伝統的に NFD を使います(かつての標準ファイルシステム HFS+ がファイル名を強制的に NFD 相当へ分解して保存する仕様でした。現在の APFS は分解こそ強制しませんが、macOS 上で作られたファイルには今も NFD 名が広く存在します)。
rsync はファイル名をただのバイト列として運ぶので、Mac の NFD 名はそのまま Linux に持ち込まれます。その結果、
- 端末やアプリによっては濁点が分離して「テ゛」のように表示される
- NFC で入力した検索文字列と一致しない(
ls | grep デがヒットしない) - NFC 名の同名ファイルと共存してしまい「同じ名前が2つある」状態になる
といった症状になります。
–iconv でファイル名を変換する
rsync 3.0 以降には、転送時にファイル名の文字コードを変換する --iconv=ローカル,リモート オプションがあります。Mac 側の文字コードとして utf-8-mac(NFD を扱う libiconv の特殊指定)を指定すると、NFD⇄NFC を変換しながら転送してくれます。
# Mac がローカル、Linux がリモートの場合 rsync -a --iconv=utf-8-mac,utf-8 src/ user@server:/path/to/dst/
指定は「ローカル,リモート」の順で固定なので、同じ書き方のまま push(Mac→Linux)でも pull(Linux→Mac)でも正しく動きます。
手元の rsync 3.4.4 で、NFD 名のファイル(「デ」が E3 83 86 E3 82 99)を --iconv=utf-8-mac,utf-8 付きでコピーして確認すると、コピー先のファイル名は NFC(E3 83 87)に変換されていました。ファイル名のバイト列は ls | xxd や ls | hexdump -C で確認できます。
注意点がいくつかあります。
- 変換はファイル名だけが対象です。ファイルの中身の文字コードは変換されません。
- リモート転送では両端の rsync が iconv 対応(3.x)である必要があります。接続先の rsync が古いと使えません。
- 変換できない文字が混ざっていると
cannot convert filename(終了コード 23)で該当ファイルがスキップされます。詳しくは rsync の終了コード一覧と意味 を参照してください。
罠:macOS 標準の rsync では –iconv が使えない
macOS Sequoia 15.4(2025年4月)から、/usr/bin/rsync の実体はライセンス上の理由で本家 rsync ではなく openrsync(BSD ライセンスの別実装)に置き換えられています。rsync --version で確認できます。
$ /usr/bin/rsync --version openrsync: protocol version 29 rsync version 2.6.9 compatible
openrsync は --iconv に対応しておらず、指定すると unrecognized option になります(手元の macOS で確認)。--iconv を使いたい場合は Homebrew の rsync(3.x)を使ってください。brew install rsync 後、パスの通し方によっては /opt/homebrew/bin/rsync(Intel Mac では /usr/local/bin/rsync)をフルパスで指定するのが確実です。
なお置き換え前の macOS に入っていた Apple 版 rsync も 2.6.9 ベースで --iconv 非対応だったので、「Mac 標準の rsync では使えない」という状況は実は昔から変わっていません。
すでに NFD 名で転送してしまったファイルの直し方
Linux 側に NFD 名のファイルができてしまった後からでも、convmv コマンドで一括正規化できます。
# まず --notest なしで実行して変更内容をプレビュー convmv -r -f utf-8 -t utf-8 --nfc /path/to/dir # 問題なければ --notest を付けて実際にリネーム convmv -r -f utf-8 -t utf-8 --nfc --notest /path/to/dir
Debian/Ubuntu なら apt install convmv、Fedora なら dnf install convmv で入ります(RHEL 系は EPEL リポジトリを有効にしてから)。既定ではプレビューのみで、--notest を付けたときだけ実際に変更される安全設計です。
Windows(Cygwin)の場合
かつて(2009年頃まで)は Cygwin 版 rsync が日本語ファイル名の変換に失敗して file has vanished や opendir failed を出す問題があり、パッチ版の cygwin1.dll に差し替える対処が知られていました。これは Cygwin 1.7(2009年12月)でロケールベースの文字コード処理が入り UTF-8 がデフォルトになったことで解消済みです。現在の Cygwin で文字コードを指定したい場合は LANG や LC_ALL 環境変数で制御します。また、いまの Windows なら WSL 上の rsync を使うほうが話が単純です(通常の Linux として振る舞います)。
この経緯の詳細と、file has vanished 警告そのものの意味は rsync の「file has vanished」警告(code 24)の意味と対処 にまとめています。
さいごに
Mac⇄Linux のファイル名化けは NFC/NFD の違いが原因で、Homebrew の rsync + --iconv=utf-8-mac,utf-8 で転送時に解決できます。macOS 標準の rsync(openrsync)では使えない点だけ注意してください。転送済みのファイルは convmv で直せます。
あわせて読みたい: