わたねこコーリング

野良プログラマ発、日々のアウトプット

【AppleScript】TimeMachine バックアップ終了を待ってアンマウント・スリープさせる

Yosemite、リリースされましたねー。けど、仕事マシンなのでアップデートはしばらくガマンの Mariyudu@実は3ヶ月前にマーヴェリクスにアプデしたばっか です。

さて、マカならバックアップは TimeMachine で決まりでしょうが、自分的にはバックアップドライブを繋ぎっぱなしにして自動バックアップという使い方はせずに、一日の仕事の終わりにバックアップドライブの電源を入れて1回だけバックアップ、という使い方をしてます。理由は、

  • 仕事中にバックアップが始まると、そのディスクアクセスで作業のパフォーマンスが落ちてしまうのがイヤ。
  • 数時間単位での世代バックアップがそれ程必要ない(プログラマなので重要作成物の履歴管理はバージョン管理システムでやってるし)。
  • 何か作業している最中のバックアップは、ファイルの状態が中途半ばのままスナップショットとられるようで精神衛生上良くない。

てな感じです。で、仕事が終わるとバックアップさせておいてフロメシテレビみたいな感じなのですが、さてマク落として寝ようと言う時にタイミング悪く再度バックアップがかかっていたりするのが一寸困りもの。この不便を解消する為に、バックアップ終了を待ってバックアップドライブを取り出してからスリープさせる、という処理を AppleScript で書いてみました。電気代も節約できるしな!

main()

on main()
	-- 設定値
	set watchCycle to 15 -- バックアップ状態監視サイクル[秒]
	set watchDuration to 3600 -- バックアップ状態監視時間[秒]
	
	-- バックアップディスクのボリュームを調べる
	set perlScript to quoted form of "print $1 if /Mount Point   : (.+)$/"
	set distMountPoint to do shell script "/usr/bin/tmutil destinationinfo | /usr/bin/perl -ne " & perlScript
	if distMountPoint = "" then
		beep
		display dialog "バックアップボリュームが見つかりません。処理を終了します。" buttons {"OK"}
		return
	end if
	
	-- バックアップの終了を待つ
	display notification "バックアップ状態を監視します…"
	set limitTime to (current date) + watchDuration
	repeat
		set currentphase to do shell script "/usr/bin/tmutil currentphase"
		if currentphase = "BackupNotRunning" then exit repeat
		if limitTime < (current date) then
			display notification "監視時間が" & watchDuration & "秒を超えたので処理を終了します。"
			return
		end if
		delay watchCycle
	end repeat
	
	-- バックアップボリュームを取り出し
	display notification "バックアップが終了したようなので、ディスクを取り出してスリープします。"
	do shell script "diskutil eject \"" & distMountPoint & "\""
	tell application "Finder" to sleep
end main

使い方はカンタン。バックアップが始まったらこのスクリプトで生成したアプリを起動して、そっとその場を立ち去るだけですw あと、アンマウントおよびスリープの際には通知センターにメッセージを残すようにしてます。

短いスクリプトなので、処理の流れはコメントでだいたい判るかと。キモはバックアップのボリュームやステータス等の情報を取得するのに、tmutil というコマンドを使ってることくらいです(出力を整形するのに perl も組み合わせてますが)。

AppleScript は普段ほとんど書かないので、こんな書き方で良いのか自信ないですが、ご参考までに。