お知らせ・ブログ一覧へ戻る

複数の自動処理が同じ作業フォルダを使うと別の結果が混ざる|中断後の再開で他の処理の成果物を拾う構造と、実行ごとにフォルダを分ける設計


複数の自動処理が同じ作業フォルダを使うと別の結果が混ざる|中断後の再開で他の処理の成果物を拾う構造と、実行ごとにフォルダを分ける設計

複数の自動処理が同じ作業フォルダを使うと別の結果が混ざる|中断後の再開で他の処理の成果物を拾う構造と、実行ごとにフォルダを分ける設計

ブログ記事の下書き、SNS投稿、店舗ページの生成、売上データの取り込み。店舗の運営でも、こうした作業を自動処理(決まった手順をプログラムに任せる仕組み)で回すことが増えています。自動処理が1本のうちは問題なく動いていたのに、2本目、3本目と増えたあたりから「なぜか別の内容で出来上がっている」という現象が起こることがあります。

先に結論を書きます。

  • 自動処理が中間ファイルを「いつも同じ1つの作業フォルダ」に書いて、次の工程がそこから読む設計は、処理が1本しか動かない前提で成り立っています
  • 同時に2本動く、あるいは途中で止まった処理を時間を空けて再開すると、その間に別の処理が書いた成果物を、自分のものとして読んでしまいます
  • 困るのは止まることではなく、エラーを1つも出さずに別物で完走してしまうことです
  • 防ぐには、①実行ごとに専用のフォルダを作る、②共有せざるを得ない場所には「同時に1本だけ」の鍵をかける、③工程の「完了」は中身を確かめてから記録する、④再開の前に成果物が自分のものかを照合する、の4点が必要です

以下、混ざる仕組み、実際にどういう形で表に出るか、混ざらない設計、混ざったときの戻し方の順で説明します。

なぜ混ざるのか:「最新版置き場」は1本しか動かない前提

自動処理の多くは、工程ごとに結果をファイルへ書き出し、次の工程がそれを読む形で作られています。このとき手軽なのが、latest(最新)のような決まった名前のフォルダを毎回使い回す作り方です。前工程は必ずそこへ書き、後工程は必ずそこから読む。場所を受け渡す必要がないので、作るのも読むのも簡単です。

ただし、この作り方は「前工程が書いてから後工程が読むまでの間に、誰もそのフォルダに触らない」ことを前提にしています。この前提が崩れる場面は、大きく3つあります。

崩れる場面 起きること
同じ処理を2本同時に動かす A用の設定の上にB用の設定が書かれ、「Aの本体+Bの設定」のような組み合わせで出来上がる
途中で止まり、時間を空けて再開する 止まっている間に別の処理が同じフォルダを上書きし、再開後の工程がその別物を読む
前工程が失敗したのに後工程が進む 前回の実行で残っていた古いファイルを読み、前回とほぼ同じものがもう一度作られる

どの場面でも、読む側のプログラムから見れば「決まった場所に、決まった形式のファイルがある」状態です。形式としては正しいので、エラーにならずに最後まで処理が進みます。 ここが、処理が止まる不具合よりも厄介な点です。

実例:止まった処理を翌朝再開すると、別テーマの記事で完成する条件

当社では、日々の作業記録から「ブログ記事」「ブログ記事を元に書き直した別媒体向けの記事」「SNS投稿」をまとめて作る自動処理を運用しています。この処理の各工程は、1つの共有の作業フォルダを「最新版置き場」として使う作りでした。同じフォルダは、毎朝決まった時刻に動く別の記事作成処理も使っています。

この構成で、次の条件が重なると混線が表に出ることを確認しています。

  • 夜間の実行中にパソコンがスリープし、通信が切れる
  • SNS投稿18件は完了。ブログ記事は通信断のためあらかじめ用意した定型文で代わりに組み立てられ、投稿も失敗。別媒体向けの記事は途中で中断
  • 翌朝、止まった所から再開する

再開すると、2つのことが同時に起きます。

1つ目は、失敗していたブログ記事の工程が「完了」として記録されていることです。代わりの定型文で組み立て、投稿に失敗しても、工程としては最後まで進んだ扱いになる作りだったため、再開時にはスキップされます。

2つ目は、別媒体向けの記事が、別テーマの記事を元に作られることです。この工程は共有フォルダにあるブログ記事を読んで書き直す作りですが、再開までの間に、朝の記事作成処理がそのフォルダを別テーマの記事で上書きしています。結果として、夜の作業記録とは関係のない内容の記事が、別媒体の管理シートに1行追加されます。

この間、エラーは1つも出ません。記録上はすべての工程が「完了」です。エラーで気づく手段はなく、出来上がった記事のタイトルを人が見て初めて分かる形です。

同じ構造は、ウェブサイトの生成でも起こります。名古屋の美容サロンFCでは、当時24店舗のサイトを1つの共通テンプレートから生成していました。店舗ごとの生成処理は、共通の設定ファイルをその店舗用に書き換えてから組み立てる作りです。これを複数店舗ぶん同時に走らせると、24店中3店で別店舗の設定が入り込んだ状態になりえます。ページは表示されるものの、店舗名が別の店になったり、他店用の画像の場所を読みに行くためトップ画像が出なかったりします。しかもその店舗用の画像ファイル自体はサーバーに正しく置かれているので、画像ファイルの有無を確かめる検査では見つかりません。見つけられるのは、全店舗のページタイトルを店舗ごとの設定と横断で突き合わせる検査です。

混ざらない設計:4つの原則

原則1:実行ごとに専用のフォルダを作り、次の工程には「その場所」を渡す

最も効く対策は、実行のたびに専用のフォルダを作ることです。フォルダ名には、実行した日時と、入力内容から作った識別子(実行ID)を入れます。構成は、たとえば次のような形です。

runs/
  20260921-0103-a1b2c3/   ← 夜の実行が書く場所
    article.md
    state.json
  20260921-0903-d4e5f6/   ← 朝の別処理が書く場所
    article.md

次の工程には「最新版置き場」ではなく、このフォルダの場所を明示的に渡します。 後工程は渡された場所のファイルだけを読むので、別の処理がいくら新しい記事を書いても影響を受けません。latest のような名前は、人が最新の結果を見に行くための近道としてだけ残し、プログラムからは読まない、と決めておくと安全です。

当社の発信用の処理では、途中から再開するための記録(どの工程まで終わったか)も、この実行IDごとに1ファイルで持っています。実行IDは入力内容から作るため、同じ入力なら同じIDになり、再開すべき記録を取り違えません。 また、テスト実行かどうかもIDの材料に含めています。こうしておくと、テストで最後まで流した記録が、本番の実行を「完了済み」に見せることがありません。

原則2:共有せざるを得ない場所には「同時に1本だけ」の鍵をかける

先ほどのサイト生成のように、共通のテンプレートを書き換える構造をすぐには変えられない場合もあります。その場合は、処理の入口に排他ロック(同時に1本しか動けないようにする鍵)を入れます。

当社の自動処理では、フォルダを1つ作ることを鍵の代わりにしています。フォルダの作成は「作れたか、既にあったか」が必ずどちらか一方に決まるため、2本が同時に鍵を取ってしまうことが起きません。

if ! mkdir "$LOCK" 2>/dev/null; then
  # 既に誰かが動いている。一定時間を過ぎた鍵だけは回収する
  echo "skip: locked"; exit 0
fi
trap 'rmdir "$LOCK"' EXIT

ポイントは3つあります。1つ目は、鍵は処理そのものに持たせることです。「同時に動かさないように気をつける」という運用上の注意だけに頼ると、いずれ守られなくなります。2つ目は、処理が異常終了して鍵が残ったときのために、一定時間(当社のブログ処理では8時間)を過ぎた鍵は回収する仕組みを入れることです。3つ目は、複数のパソコンでフォルダを同期している環境では、自動処理を動かすパソコンを1台に固定することです。同期には時間差があるため、鍵はパソコンをまたいだ同時実行までは確実に防げません。

原則3:工程の「完了」は、中身を確かめてから記録する

実例の1つ目の問題は、失敗した工程が「完了」と記録されていたことでした。工程の終わりに記録を付けるのではなく、成果物が条件を満たしたときだけ「完了」と記録します。

  • 記事の工程なら、本文の文字数、見出しの数、投稿先から記事の番号が返ってきたか
  • 代わりの定型文で組み立てた、投稿に失敗した、といった「予備の動き」が1回でも出たら、完了ではなく「要確認」として残す
  • 1件書き込むごとにその結果を確定させ、次の件へ進む

当社の発信用の処理では、生成と書き込みを分けて記録しています。通信断で処理が約40分粘った末に止まり、それまでの生成が無駄になるケースに備えて、生成済みの本文は先に記録へ保存しておきます。書き込みは3回まで(2秒・5秒・10秒と間隔を空けて)試し、だめなら記録を残して止まります。再開時は生成をやり直さず、書き込みだけを再試行します。

「最後に成功した時刻を見る」という監視の考え方は「自動処理の監視は「最後に成功した時刻」を見る」で、保存完了の表示を信用せず開き直して確かめる方法は「自動投稿で「保存完了」と出たのに中身が空になるとき」で解説しています。

原則4:再開する前に「その成果物は自分のものか」を照合する

原則1の形に作り替えるまでの間は、再開の前に作業フォルダの成果物が自分の実行のものかを確かめます。 タイトルや作成時刻が、再開しようとしている実行と一致しているかを見るだけで、実例の混線は防げます。

また、前工程が失敗したときに後工程を進めないことも必要です。前工程の成果物が無い、または失敗の記録がある場合は、古いファイルが残っていても読まずに後工程をスキップするようにします。前回の記事とほぼ同じ内容の記事がもう一度作られる問題は、この確認で止められます。

長時間の処理は、パソコンをスリープさせない設定で動かすことも忘れないでください。実例でも、中断のきっかけはスリープによる通信断でした。

混ざってしまったときの戻し方

混線に気づいたら、次の順で戻します。

  1. 誤って入った成果物を1件に特定する。作成時刻とタイトルが一致し、該当が1件だけで、まだ公開や投稿に使われていないことを確かめてから消す
  2. 「完了」の記録から、やり直す工程だけを外す。実例ならブログ記事と別媒体向けの記事の2工程
  3. その工程だけを再実行する。完了済みの工程(実例ならSNS投稿18件)は記録どおりスキップされ、二重に投稿されないことを確かめる
  4. 全件を横断で突き合わせる。店舗サイトなら、全店舗のページタイトルと画像の場所が、それぞれの店舗の設定と一致しているかを確かめる

1で「該当が1件だけ」を確かめるのは、条件が緩いまま消すと正しい成果物まで巻き込むためです。サイトの場合は、修正後も閲覧者のブラウザに古いプログラムが残って誤った表示が続くことがあるため、古い版への対応も含めて確認します。

自動処理を増やす前のチェックリスト

確認項目 確認する理由
実行ごとに専用のフォルダを作っているか 別の処理の成果物を読まないため
次の工程に「場所」を明示的に渡しているか 最新版置き場を読む限り、混線は防げない
共有する場所に排他ロックがあるか 同時実行で設定が混ざるのを防ぐ
残った鍵を回収する仕組みがあるか 異常終了後に処理が永遠に止まらないため
「完了」は中身の検査を通ったときだけか 失敗が完了として記録されるのを防ぐ
再開前に成果物の持ち主を照合しているか 止まっている間の上書きに気づくため
公開後に全件を横断で突き合わせているか 形式が正しい混線は、個別の検査では見えない

制作会社や外部の担当者に自動処理を任せている場合も、このうち「実行ごとにフォルダを分けていますか」「途中で止まったとき、どこから再開しますか」の2点を聞くだけで、設計の考え方がおおよそ分かります。多店舗のサイトで共通部分と店舗ごとの部分をどう分けるかは「店舗が増えてもホームページが崩れない作り方」で、取り込み後の突合については「売上データを取り込んだら金額が合わないときの原因」で整理しています。

まとめ

  • 決まった1つの作業フォルダを使い回す自動処理は、処理が1本しか動かない前提で成り立っている
  • 同時実行、時間を空けた再開、前工程の失敗のいずれかが起きると、他の処理や前回の成果物を自分のものとして読む
  • 混線は形式が正しいため、エラーを出さずに別物で完走する。記録上もすべて「完了」になりうる
  • 対策は、実行ごとの専用フォルダ、共有する場所の排他ロック、中身を確かめてからの完了記録、再開前の持ち主の照合の4つ
  • 混ざったときは、誤った成果物を1件に特定して消し、やり直す工程だけを再実行し、最後に全件を突き合わせる

自動処理は、1本目を作るときより、2本目を足すときのほうが設計の前提が崩れやすいものです。処理を増やす前に「この処理はどのフォルダを読み書きしているか」を一覧にしておくことが、止まらないのに間違っている、という最も気づきにくい不具合を防ぐいちばん確実な方法です。

関連記事

2026.10.04

発注の記録を月別に集計する表は元のシートと分けて作る|元データはIMPORTRANGEでつなぎ、月ごとのシートは「対象月」のセル1つで切り替える作り方と、件数・数量の検算

2026.10.04

多店舗の店舗一覧ページは地図とテキストの一覧を両方置く|県→エリア→ピンで選ばせる地図と、HTMLに最初から書いた店舗カードの作り方、公開前に電話・営業時間・予約先を突き合わせる手順

2026.10.03

実績の画面をSNSに載せるときの匿名化|市名だけ伏せても駅名・地名で店は分かる。店名は丸ごと置き換え、文字認識で実名の残りを機械的に照合する手順


お知らせ・ブログ一覧へ戻る