# [メタ情報]
# 識別子: メディアおよびJSONをXserverへ更新および自動復帰_exe
# システム名: 未分類
# 技術種別: Misc
# 機能名: Misc
# 使用言語: Shell Script
# 状態: 実行用
# [/メタ情報]
要約:Dropbox → Xserver 同期用のメインスクリプトは、pmedia・mmedia・meta_gd_wp_data を Homebrew 版 rsync で転送し、SSH鍵を自動ロードして毎分同期するよう LaunchAgent から実行される。ログは /tmp と $HOME/scripts/logs に記録される。しかし rsync が残留してフリーズすることがあるため、毎日 3:30 に自動復旧スクリプトが動作し、pmedia/mmedia 関連の rsync プロセスを検出して kill し、メインの LaunchAgent(com.xxxxxxxxm1.sync_dropbox_xserver_m1)を unload/load し直して正常状態へ戻す仕組みとなっている。
/Users/xxxxxxxxm1/scripts/sync_dropbox_xserver_m1.sh
#!/bin/bash
# ===== LaunchAgent 用:PATH を明示的に設定 =====
export PATH="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
export LANG=en_US.UTF-8
# ===== rsync: Homebrew 版を絶対パスで指定 =====
RSYNC="/opt/homebrew/bin/rsync"
# ===== ローカルパス =====
LOCAL_DROPBOX_BASE="/Volumes/NO3_SSD/Dropbox/dropbox_1"
# pcloud_library.json など JSON 類が入るディレクトリ(Python が書き出している場所)
LOCAL_META_DIR="$HOME/meta_gd_wp_data"
# ===== ログディレクトリ =====
LOG_DIR="$HOME/scripts/logs"
# ===== Xserver 接続情報 =====
SSH_USER="xxxxxxxx"
SSH_HOST="xxxxxxxx.xsrv.jp"
SSH_PORT="10022"
SSH_KEY="$HOME/.ssh/id_rsa_sync"
# ===== ログディレクトリ作成 =====
mkdir -p "$LOG_DIR"
# ---- /tmp にトレース(launchd 実行確認) ----
TS="$(date '+%Y-%m-%d %H:%M:%S')"
echo "[$TS] sync_dropbox_xserver_m1.sh START (pid=$$, user=$(id -un))" >> /tmp/sync_dropbox_trace.log
echo "[$TS] ==== sync_dropbox_xserver_m1.sh START ====" >> "$LOG_DIR/sync_dropbox_debug.log"
# ===== launchd 用に ssh-agent を起動して鍵をロード =====
eval "$(ssh-agent -s)" >/dev/null 2>&1
ssh-add "$SSH_KEY" >/dev/null 2>&1
# ---------------------------------------------------------
# 1) pmedia → Xserver: wp-content/pmedia
# ---------------------------------------------------------
echo "[$(date '+%Y-%m-%d %H:%M:%S')] rsync pmedia START" >> "$LOG_DIR/sync_dropbox_debug.log"
"$RSYNC" -avz --iconv=UTF-8-MAC,UTF-8 \
--delete --perms --chmod=Da+rx,Fa+r \
-e "ssh -i $SSH_KEY -p $SSH_PORT" \
--exclude='@esDir' \
"$LOCAL_DROPBOX_BASE/pmedia/" \
"$SSH_USER@$SSH_HOST:/home/xxxxxxxx/xxxxxxxx.com/public_html/wp-content/pmedia/" \
>> "$LOG_DIR/rsync_pmedia.log" 2>>"$LOG_DIR/rsync_pmedia_error.log"
P_RET=$?
echo "[$(date '+%Y-%m-%d %H:%M:%S')] rsync pmedia END (exit=$P_RET)" >> "$LOG_DIR/sync_dropbox_debug.log"
sleep 1
# ---------------------------------------------------------
# 2) mmedia → Xserver: wp-content/mmedia
# ---------------------------------------------------------
echo "[$(date '+%Y-%m-%d %H:%M:%S')] rsync mmedia START" >> "$LOG_DIR/sync_dropbox_debug.log"
"$RSYNC" -avz --iconv=UTF-8-MAC,UTF-8 \
--delete --perms --chmod=Da+rx,Fa+r \
-e "ssh -i $SSH_KEY -p $SSH_PORT" \
--exclude='@esDir' \
"$LOCAL_DROPBOX_BASE/mmedia/" \
"$SSH_USER@$SSH_HOST:/home/xxxxxxxx/xxxxxxxx.com/public_html/wp-content/mmedia/" \
>> "$LOG_DIR/rsync_mmedia.log" 2>>"$LOG_DIR/rsync_mmedia_error.log"
M_RET=$?
echo "[$(date '+%Y-%m-%d %H:%M:%S')] rsync mmedia END (exit=$M_RET)" >> "$LOG_DIR/sync_dropbox_debug.log"
sleep 1
# ---------------------------------------------------------
# 3) meta_gd_wp_data → Xserver: _secure/wp_json
# (pcloud_library.json / videoct.json / videoembed.json など)
# ---------------------------------------------------------
echo "[$(date '+%Y-%m-%d %H:%M:%S')] rsync meta_gd_wp_data START" >> "$LOG_DIR/sync_dropbox_debug.log"
"$RSYNC" -avz \
--delete --perms --chmod=Da+rx,Fa+r \
-e "ssh -i $SSH_KEY -p $SSH_PORT" \
"$LOCAL_META_DIR/" \
"$SSH_USER@$SSH_HOST:/home/xxxxxxxx/xxxxxxxx.com/public_html/_secure/wp_json/" \
>> "$LOG_DIR/rsync_meta_gd_wp_data.log" 2>>"$LOG_DIR/rsync_meta_gd_wp_data_error.log"
J_RET=$?
echo "[$(date '+%Y-%m-%d %H:%M:%S')] rsync meta_gd_wp_data END (exit=$J_RET)" >> "$LOG_DIR/sync_dropbox_debug.log"
exit 0
/Users/xxxxxxxxm1/Library/LaunchAgents/com.xxxxxxxxm1.sync_dropbox_xserver_m1.plist
Label
com.xxxxxxxxm1.sync_dropbox_xserver_m1
ProgramArguments
/bin/bash
/Users/xxxxxxxxm1/scripts/sync_dropbox_xserver_m1.sh
RunAtLoad
StartInterval
60
StandardOutPath
/tmp/sync_dropbox_xserver_m1.out
StandardErrorPath
/tmp/sync_dropbox_xserver_m1.err
上と合わせて、毎朝3:30にrsyncの残留をチェックして、
残っていればkill unload loadする。
/Users/xxxxxxxxm1/scripts/sync_xserver_selfheal.sh
#!/bin/bash
# pmedia / mmedia 同期の自動復旧スクリプト
# - pmedia / mmedia 関連の rsync が残っていれば kill
# - メイン同期 LaunchAgent(com.xxxxxxxxm1.sync_dropbox_xserver_m1)を reload
# ※sync_dropbox_xserver_m1.sh 本体は変更しない
export PATH="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
export LANG=en_US.UTF-8
LOG_DIR="$HOME/scripts/logs"
SELFHEAL_LOG="$LOG_DIR/sync_xserver_selfheal.log"
PLIST="$HOME/Library/LaunchAgents/com.xxxxxxxxm1.sync_dropbox_xserver_m1.plist"
# ログディレクトリ作成(既存の sync_dropbox_xserver_m1.sh と同じ場所)
mkdir -p "$LOG_DIR"
{
echo "===== $(date '+%Y-%m-%d %H:%M:%S') self-heal START ====="
# 1) pmedia / mmedia 関連の rsync プロセスを探して kill
PIDS_P=$(pgrep -f "rsync .*pmedia" || true)
PIDS_M=$(pgrep -f "rsync .*mmedia" || true)
RSYNC_PIDS=""
if [[ -n "$PIDS_P" ]]; then
RSYNC_PIDS="$RSYNC_PIDS $PIDS_P"
fi
if [[ -n "$PIDS_M" ]]; then
RSYNC_PIDS="$RSYNC_PIDS $PIDS_M"
fi
if [[ -n "${RSYNC_PIDS// /}" ]]; then
echo "🔍 残留 rsync プロセス検出: $RSYNC_PIDS"
for pid in $RSYNC_PIDS; do
echo "➡ kill $pid"
kill "$pid" 2>/dev/null || echo "⚠ kill 失敗: $pid"
done
sleep 2
else
echo "✅ pmedia/mmedia 関連 rsync 残留なし"
fi
# 2) メイン同期 LaunchAgent の reload
if [[ -f "$PLIST" ]]; then
echo "🔁 LaunchAgent reload: $PLIST"
launchctl unload "$PLIST" 2>/dev/null || echo "ℹ unload でエラー (無視可)"
launchctl load "$PLIST" || echo "⚠ launchctl load でエラー"
else
echo "⚠ メイン同期 plist が見つかりません: $PLIST"
fi
echo "===== $(date '+%Y-%m-%d %H:%M:%S') self-heal END ====="
} >>"$SELFHEAL_LOG" 2>&1
/Users/xxxxxxxxm1/Library/LaunchAgents/com.xxxxxxxxm1.sync_xserver_selfheal.plist
Label
com.xxxxxxxxm1.sync_xserver_selfheal
ProgramArguments
/bin/bash
/Users/xxxxxxxxm1/scripts/sync_xserver_selfheal.sh
StartCalendarInterval
Hour
3
Minute
30
StandardOutPath
/tmp/sync_xserver_selfheal.out
StandardErrorPath
/tmp/sync_xserver_selfheal.err