Macの常駐処理が登録されたまま止まり続けるとき|書類フォルダのiCloud同期でファイルが中身なしになる原因と、置き場所を変える直し方
Macの常駐処理が登録されたまま止まり続けるとき|書類フォルダのiCloud同期でファイルが中身なしになる原因と、置き場所を変える直し方
予約データの取り込みや毎朝の売上集計を事務所のMacに常駐させる構成は、サーバーを借りずに始められます。
ところが、この「Macに常駐させる」構成には、エラー通知も出ないまま何週間も止まり続ける壊れ方があります。原因として見落とされやすいのが、プログラムやデータの置き場所がiCloudの同期フォルダの中にあることです。
結論から書きます。
- 常駐させるプログラム・データベース・ログは、「書類」「デスクトップ」「iCloud Drive」の中に置かない。 置き場所は
~/dev/のような自分で作ったフォルダや、~/Library/Application Support/(アプリのデータ置き場)、ログは~/Library/Logs/にする - すでに同期フォルダの中で動いているなら、まず中身がクラウドに退避された「空のファイル」が無いかを確認し、手元に戻してから、実行時に書き換わるフォルダだけ同期の対象から外す(応急処置)。そのうえで、プログラム一式を同期の外へ移す(恒久対処)
- 死活は「登録されているか」ではなく、「仕事の結果が増えているか」で見る。 一覧に名前が出ていても、裏では起動と即死を延々と繰り返していることがあるため
以下、なぜ止まるのか、どう見分けるのか、どう直すのかを、実際にMacで常駐させていた処理で確認した数字をもとに説明します。
なぜiCloud同期の中に置くと止まるのか
「書類」と「デスクトップ」は、設定によってiCloud Driveの一部になる
macOSのiCloud設定には「デスクトップと書類フォルダ」を同期する項目があります。これをオンにすると、ホームフォルダの「書類」(~/Documents)と「デスクトップ」は、見た目は今までどおりでも、実体はiCloud Driveの中に移ります。
本人は「書類フォルダに置いただけ」のつもりでも、そのファイルはクラウド同期の管理下に入っています。
容量最適化で、ファイルの中身だけがクラウドへ退避される
同じくiCloud設定の「Macストレージを最適化」がオンだと、macOSはディスクの空きが少なくなったとき、しばらく開かれていないファイルの中身をクラウドに退避し、名前と大きさの情報だけを手元に残します。この状態のファイルを、macOSの用語で「dataless(データレス)」と呼びます。
人がFinderでファイルを開くと、その場で中身がダウンロードされるので、普段は意識しません。問題は、人の操作ではなく、裏で動いている常駐処理がそのファイルを読みに行ったときです。
バックグラウンドの処理からは、中身を取り戻せずに読み込みが失敗する
Macで常駐処理を動かす標準の仕組みは「launchd(ローンチデー)」で、ユーザー単位の常駐は「LaunchAgent(ローンチエージェント)」として登録します。
この仕組みから起動された処理がdatalessのファイルを読もうとすると、中身のダウンロードが行われず、読み込みがエラーで返ってくることがあります。実測では、次のエラーで処理が落ちていました。
| 見えたもの | 意味 |
|---|---|
Unknown system error -11, read(Node.jsのエラー表示) |
エラー番号11=macOSの EDEADLK(Resource deadlock avoided)。datalessのファイルを読めなかった |
終了コード 78(EX_CONFIG) |
起動の設定に問題があり、処理が始まる前に失敗した。実例では出力先が同期下にあり、出力先を移したら直った |
同じプログラムを人がターミナルから手で動かすと成功するのが特徴で、「なぜか常駐だと動かない」という切り分けの迷路に入りがちです。
なお、launchdには MaterializeDatalessFiles(datalessのファイルを取り戻す方針)という設定もありますが、読めるようになっても競合コピーや同期の負荷は解決しません。常駐物は最初から同期の外に置くのが確実です。
実際に起きうること:止まっているのに気づけない
やっかいなのは、止まっていることが表に出てこない点です。Macに常駐させていた2つの処理で、次の状態を確認しました。
| 処理 | 置き場所 | 止まっていた期間 | 見えていた状態 |
|---|---|---|---|
| 案件メールを取り込んで一覧化する常駐処理 | 「書類」フォルダ内(iCloud同期下) | 約25日 | 起動→即死→自動再起動を18,746回繰り返していた。datalessになっていたのは、起動時の排他用ファイルやデータベースの更新記録ファイルなど43件 |
| 毎朝データを取りに行く定期処理 | 出力ログの置き場所がiCloud同期下 | 48日間 | 起動自体は繰り返されていた(実行回数は増えていた)が、終了コード78で起動前に失敗。ログは1行も残っていなかった |
前者は「落ちたら自動で再起動する」設定のため、一覧では登録されたままでした。後者はログ自体が書けない壊れ方なので、ログを見ても何も書いていません。「ログが無い=動いていない」ではなく、「ログが無い=起動の手前で死んでいる」こともある、ということです。
同期フォルダの中では、ほかにも副作用が出る
止まる以外の副作用も起こりえます。
- 競合コピーが量産される。 書き換わり続けるファイルに対して、iCloudが「ファイル名 2」「ファイル名 3」のような複製を作ります。前者の処理では、排他用ファイルやデータベースの複製が42件できていました。プログラムがこれを読むと、さらに別の不具合につながります
- 同期の帯域を食い、ほかのファイルの同期が遅れる。 常駐処理のログが同期フォルダ内で1.4GBまで膨らみ、書き換わるたびに再アップロード(確認時点で試行23回)が続いていた例では、同じ時期に、2台のMac間で共有している別のファイルが約3時間遅れて届いていました(同期の占有が影響したとみられます)
見分け方:3つの確認
常駐処理が止まっている気がしたら、次の順で確認します。ターミナルを使いますが、コマンドはコピーして貼るだけです。
1. 実行回数と最後の終了コードを見る
launchctl print gui/$(id -u)/登録名
出力の中の runs(起動された回数)と last exit code(最後の終了コード)を見ます。
runsが数千・数万と異常に多い → 起動と即死を繰り返しているlast exit codeが78→ 起動の手前で失敗している(出力先・プログラム・作業フォルダのパスを疑う)- 終了コードが
1などでもrunsが多ければ、エラーログで-11を探す(実例の1件目は終了コード1でした)
launchctl list の一覧だけでは起動回数が分からないため、print で詳細を見るのがポイントです。
2. 置き場所が同期下かを確認する
登録内容(~/Library/LaunchAgents/ にある設定ファイル)を開き、次の項目のパスを確認します。
- 実行するプログラムのパス
- 作業フォルダ(
WorkingDirectory) - 標準出力・エラー出力の書き込み先(
StandardOutPath/StandardErrorPath)
どれか一つでも ~/Documents・~/Desktop・~/Library/Mobile Documents/(iCloud Driveの実体)で始まっていれば、この記事の原因に当てはまる可能性があります。
3. 中身が退避されたファイルが無いかを数える
find フォルダのパス -flags +dataless
フォルダの下の階層まで含めて、datalessのファイルだけが一覧で出ます(ls -l% でも1階層分なら権限欄の末尾に % が付きます)。1件でも出れば、常駐処理からは読めない状態です。
直し方:応急処置と恒久対処を分ける
応急処置:中身を取り戻し、書き換わるフォルダだけ同期から外す
その日のうちに処理を再開させたい場合の手順です。
- 常駐処理を止める。 再起動の繰り返し中に作業すると、取り戻したそばから壊れることがあります
- 状態一式をバックアップする。 データベースや設定を、同期の外(例:
~/Library/Application Support/の下)にまとめて圧縮して保存します - datalessのファイルを手元に戻す。 人の操作(ターミナルから読む、Finderで開く)なら中身がダウンロードされます。手順「3」の
findで何も出なくなるまで行います - 競合コピーを退避する。 「〜 2」「〜 3」の複製は削除せず、バックアップ先へ移します。中身が本体と違うことがあるためです
- 実行時に書き換わるフォルダだけ、同期の対象から外す。 フォルダ名の末尾に
.nosyncを付けるとiCloudの同期対象から外れます(公式文書には無い、経験的に知られた挙動です)。プログラムが元のパスを参照している場合は、元の名前でシンボリックリンク(別名)を置けば、プログラムを書き換えずに済みます
mv .runtime .runtime.nosync
ln -s .runtime.nosync .runtime
- ログの書き込み先を
~/Library/Logs/に変える。 実例では、ログの出力先を同期の外へ変えた翌朝から、48日間止まっていた定期処理が正常に完走しました。終了コード78はプログラムや作業フォルダのパスの誤りでも出るため、ほかのパスもあわせて確認します - 再起動して、仕事の結果が増えることを確認する(後述)
.nosync 化には一つ注意があります。名前を変えた直後、iCloudが空の「〜 2」フォルダを作ることがあるため、作業後に空の複製を消しておきます。ビルドで作られるフォルダ(dist など)も実行時に読まれるなら同じ扱いです。さらに、別名(リンク)だけはもう1台のMacへ同期され、リンク先の .nosync は届かないため、2台目では参照先の無いリンクになります。応急処置は1台で使う前提にとどめます。
恒久対処:プログラム一式を同期の外へ移す
応急処置では、プログラム本体や部品(node_modules など)は同期下に残ったままです。容量最適化の対象になるリスクは消えていません。根本的には、次のように置き場所そのものを変えます。
| 置くもの | 置き場所の例 |
|---|---|
| プログラム一式(ソース・部品) | ~/dev/プロジェクト名/ など、自分で作ったフォルダ |
| データベース・実行時の状態 | ~/Library/Application Support/プロジェクト名/ |
| ログ | ~/Library/Logs/プロジェクト名/ |
移したら、LaunchAgentの設定ファイル内のパスを全て書き換え、登録し直します。設定ファイルには ~ を使わず、/Users/ユーザー名/Library/Logs/… のような絶対パスで書きます。登録を外した直後に再登録すると入出力エラーで失敗することがあるため、数秒おいてからやり直すと通ります。
2台のMacで同じプログラムを使うなら、iCloudではなくGitなどのバージョン管理で受け渡します。同期フォルダは「人が開く書類」のための仕組みで、「機械が秒単位で書き換えるファイル」向けではない、と割り切るのが判断基準です。
再発を防ぐ:死活は「結果が増えているか」で見る
常駐処理は別の理由でもまた止まりえます。止まったら数日以内に気づける見方にしておきます。
- 見るのは「登録されているか」ではなく「成果物が増えているか」。 取り込み件数、最後に処理した日時、出力ファイルの更新日時など、仕事の結果そのものの鮮度を見ます
- ログが無いことを「異常なし」と読まない。 終了コード78のように、ログが書けない壊れ方があります
- 画面やAPIを持つ処理なら、応答が返るかを定期的に確かめる。 一覧に名前があることと、実際に応答することは別です
この「結果の鮮度で監視する」考え方は、自動処理の監視は「最後に成功した時刻」を見ると、自動処理が「成功」と出ているのに反映されないときで詳しく書いています。Macのメールに届く添付ファイルを毎日取り込む構成の作り方は、Macのメールに毎日届く添付Excelを自動で取り込む方法も参考にしてください。
常駐処理を置く前のチェックリスト
- プログラム・データベース・ログのどれも
~/Documents・~/Desktop・iCloud Driveの中に無いか - LaunchAgentの出力先(
StandardOutPath/StandardErrorPath)が~/Library/Logs/などのローカルにあるか - 2台以上のMacで使うなら、同期ではなくバージョン管理で受け渡しているか
- 担当者が
launchctl printでrunsとlast exit codeを確認できるか - 成果物の最終更新日時を見て、止まったら数日以内に気づける仕組みがあるか
まとめ
- Macの「書類」「デスクトップ」は、iCloud設定によって同期フォルダの一部になる。そこに常駐処理を置くと、容量最適化で中身が退避された(dataless)ファイルを読めず、処理が即死することがある
- 見分けるサインは
Unknown system error -11(EDEADLK)と終了コード78(EX_CONFIG)。ただしどちらも別の原因でも出るため、置き場所の確認とセットで判断する - 実測では、起動と即死の繰り返しが18,746回、ログの残らない停止が48日間。どちらも登録されたままだった
- 応急処置は「バックアップ→中身を取り戻す→競合コピーを退避→書き換わるフォルダを
.nosync化→ログを~/Library/Logs/へ」。恒久対処はプログラム一式を同期の外へ移すこと - 死活は「登録されているか」ではなく「仕事の結果が増えているか」で見る
graciautoでは、美容室・店舗ビジネスの予約データ取り込みや売上集計などの業務自動化を、置き場所や監視の設計まで含めて支援しています。社内で動かしている自動処理が止まりがちな場合も、お問い合わせからご相談ください。