猫の手なら貸せる

いろいろ共有できたらいいなとおもってます

Mac→Ubuntuのlaunchd及びrsyncに関するエラーについて

rsyncとlaunchd(Mac推奨のcronの後続)を用いて、定期的にバックアップ取ろうとしていた際につまづいたことがいくらかあったので備忘録です。

元記事:
nkhnd.hatenablog.jp

環境

転送元:MacbookAir (2019 Retina) Mojave
転送先:RaspberryPi (Sambaによる共有)

権限があるディレクトリにも関わらずOperation not permitted

事象

このエラーはユーザーのLibraryディレクトリなどを、launchdでrsync同期を行おうとした際に発生しました。
以下はMacバイスのバックアップをリモートディレクトリにrsyncしようとした際に発生した例です。

2019/12/18 06:48:02 [29222] rsync: opendir "/Users/nkmm/Library/Application Support/MobileSync/Backup/." failed: Operation not permitted (1)
rsync: opendir "/Users/nkmm/Library/Application Support/MobileSync/Backup/." failed: Operation not permitted (1)
2019/12/18 06:48:02 [29222] IO error encountered -- skipping file deletion
IO error encountered -- skipping file deletion
2019/12/18 06:48:02 [29222] .d..tp...... ./
2019/12/18 06:48:02 [29222] rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1209) [sender=3.1.3]
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1209) [sender=3.1.3]

ファイル権限自体はきちんとユーザーが所持しています。

MobileSync $ ll
total 8
drwxr-xr-x   4 nkhnd  staff   128 12 18 07:09 .
drwx------+ 32 nkhnd  staff  1024 12 16 21:18 ..
drwxr-xr-x   4 nkhnd  staff   128 12 18 06:45 Backup  #←きちんとrsyncを行うユーザーが所持
MobileSync $ cd Backup && ll
NekoBook:Backup nkmm$ ll
total 0
drwxr-xr-x    4 nkhnd  staff   128 12 18 06:45 .
drwxr-xr-x    4 nkhnd  staff   128 12 18 07:09 ..
drwxr-xr-x  262 nkhnd  staff  8384 12 17 06:35 (Apple DeviceのIDをもつディレクトリ)
drwxr-xr-x  262 nkhnd  staff  8384 12 17 06:38 (Apple DeviceのIDをもつディレクトリ)

また、「システム詳細設定」「セキュリティとプライバシー」におけるターミナルの「フルディスクアクセス」は許可しています。

f:id:nkhnd:20191218071304p:plain

発生理由と対処法

(追記) 良さも悪さもできるbashにフルディスクアクセスを許可するのは、セキュリティ的にだいぶ怪しいため非推奨です。
通常アクセスに制限がかけられている~/Library以下などは、直接アクセスせず、アクセスしたい場所を安全なディレクトリへシンボリックリンクすることをお勧めします。私もこの方法に移行しました。
例えばiOSバイスiTunesバックアップが作成される~/Library/Application Support/MobileSync/Backup/を新たに作成した~/backフォルダに自動的に転送するには、次の方法でシンボリックリンクを作成します。

mv ~/Library/Application\ Support/MobileSync/Backup/* ~/back/ #データを退避
rmdir ~/Library/Application\ Support/MobileSync/Backup/ #元ディレクトリは削除
ln -s ~/back ~/Library/Application\ Support/MobileSync/Backup
 #backディレクトリへのシンボリックリンクをMobileSync内でBackupという名前で作成

こうしてやると、フルディスクアクセスを使わず、launchdがディレクトリにアクセスできるようになります。


以下過去の文章。(非推奨)

ディレクトリでは正常にrsyncできることから、MacOSの問題であると切り分けた所、ターミナルではなく、launchdで動作させるプログラム本体を追加するという解決策が提示されました。
mac-ra.com
しかし、rsyncにフルディスクアクセスを許可しても反応しないため、さらに調べた所、bashにフルディスクアクセスを許可し、bashからrsyncを起動すれば正常にアクセスできました。
eclecticlight.co
フルディスクアクセスにbashを設定します。
f:id:nkhnd:20191218074903p:plain plistではrsyncbash越しに起動するように設定します。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
 <key>Label</key>
 <string>devicessync</string>
 <key>ProgramArguments</key>
 <array>
  <string>/bin/bash</string>
  <string>/Users/nkhnd/rsync.sh</string>
  <string>/Users/nkhnd/Library/Application Support/MobileSync/Backup/</string>
  <string>pi@raspberrypi.local:/mnt/Backup/</string>
  <string>/Users/nkhnd/backup.log</string>
 </array>
 <key>StartCalendarInterval</key>
 <dict>
  <key>Hour</key>
   <integer>7</integer>
  <key>Minute</key>
   <integer>45</integer>
 </dict>
 <key>StandardOutPath</key>
...(省略)...

動作確認を行います。

2019/12/18 07:45:00 Start rsync /Users/nkhnd/Library/Application Support/MobileSync/Backup/ => pi@raspberrypi.local:/mnt/Backup/
2019/12/18 07:45:00 [29398] building file list
2019/12/18 07:45:01 [29398] .d...p...... ./
...(省略)...

無事動作しました。

iconvを指定済みにも関わらずrsync --deleteが更新のないファイルを削除

事象

iconvで文字コードの変換規則を設定しているにも関わらずSambaでマウントしているディレクトリ宛rsync --deleteを行うと、2回目の同期にかかわらず更新のないファイルを削除してしまうことがあります。

以下は実行コマンドの例です。Sambaによって/Volumes/Storageをマウントしています。

$ rsync -auz --delete --iconv=UTF-8-MAC,UTF-8 --exclude '.*' --log-file=test.log /Users/nkhnd/dir /Volumes/Storage/back/

発生理由と対処法

Sambaでマウントしているディレクトリに対しては--iconvが機能しないようです。

Sambaを利用せず、SSH接続を前提にしたパスを指定することで解決します。-eオプションで鍵を指定することが可能です。

rsync -auz --delete --iconv=UTF-8-MAC,UTF-8 --exclude '.*' -e "ssh -i /Users/nkmm/.ssh/id_ed25519" --log-file=test.log /Users/nkmm/dir nas@raspberrypi.local:/mnt/Storage/back/ 

SambaだけでなくsshFUSEを使っていても発生していたため、rsyncでネットワーク越しかそうではないかでリストチェックがことなるのかもしれません。

launchdでrsyncがiconvオプションを認知しない

事象

launchdでシェル内のrsyncを呼びだす場合、及びlaunchdで直接rsyncを実行する際、--iconvオプションが指定できないことがあります。
homebrew等でlibiconvはインストール済みで、記法に間違いはありません。

rsync: --iconv=UTF-8-MAC,UTF-8: unknown option
rsync error: syntax or usage error (code 1) at /BuildRoot/Library/Caches/com.apple.xbs/Sources/rsync/rsync-52.200.1/rsync/main.c(1337) [client=2.6.9]

発生理由と対処法

launchd実行時のシェルでは/usr/local/binにパスが通っていません。
以下は手動・及びlaunchdにenvコマンドを実行させた結果です。

$ cat launchdEnv.log #launchdのenv出力内容
---------- env ----------
...(省略)...
PATH=/usr/bin:/bin:/usr/sbin:/sbin
...(省略)...
$ env #ターミナル上でenvを入力した際の内容
...(省略)...
PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
...(省略)...

また、whichコマンドでターミナル上で実行できるrsyncのパスを調べてみます。

$ which -a rsync
/usr/local/bin/rsync
/usr/bin/rsync

どうやらrsyncは二種類(homebrewでインストールしたもの、Mac標準でインストールされているもの)あるようです。
launchdでは/usr/local/binにパスは通っていないので、plistではフルパス(/usr/local/bin/rsync)で実行する必要があります。
launchdで呼び出すシェルスクリプトについての記述もrsyncではなく/usr/local/bin/rsyncと記述しましょう。


2020/05/22

またk8sコンテナ越しにSambaでファイルを共有していて、rsync、iconvでつまづいたので見ています。備忘録をつけておいてよかった。