Detect if Time Machine is active

This is potentially a dumb question, but I’ve spent the last half hour fighting it - is there any reason why using a network share in place of “myVolume” would cause this script to not work (giving a ‘no such file or directory’ error)?

Yes, it is. As you gave no further information, I assumed you’re using just a local volume.
The Time Capsule for example uses a sparse image, but in this case you could check the existence of the mounted image

My apologies; the volume is stored on a Time Machine server on the network, accessed (of course) with AFP.

I am thinking of just telling Finder to mount the drive, and then to use that volume name as myVolume. Then, when the script finishes, the drive could be unmounted. Does that make sense?

the script should work with a normal AFP share, but it could be, that you have some special characters
in the computer name, which are resolved by the OS. Take a look at the backup volume and try to hard-code the path
to the backup folder

No matter what I do, it’s failing out at

 if not ((do shell script "/bin/ls " & quoted form of POSIX path of backupFolder)

Saying that there’s no such file or directory. I have tried entering the IP of the system followed by the path to the directory, I’ve tried entering the hostname, and I’ve tried about five variants of each - no luck. It seems like something is wrong other than the mounting of the drive, because even though the script fails the backup completes successfully. It’s apparently failing when trying to look for the inprogress file.

can you please open the backup folder on your shared volume (the one with the yyyy-mm-dd-HHMMSS folders) and command-click in the title of the window.
You will see the path. As mentioned before probably you have special characters in the host name (e.g. the OS will change Fooruman’s computer to Foorumans-computer)

Though it’s located on a server, it just shows up as Volumes/Backups for the path of the .sparsebundle. The sparsebundle’s name is dkschroeder-m-25’s Mac mini_############.sparsebundle, which gets mounted also in /Volumes. The #s represent my MAC address, of course.

I did try replacing the special characters with their POSIX equivalents, and had no luck.

Thanks so much for all the help, StefanK, it seems like this is almost working.

My Time Capsule backup has the path /Volumes/Backup of [hostname]/Backups.backupdb/[hostname]/

Sorry, there are several options to use Time Machine, it’s very difficult to guess the exact configuration

PS: It’s strongly recommended to avoid any special character in the host names

Maybe this is a better solution, or at least one that can let me start doing my work:

Is there a way for the script to just find out what the currently set backup volume is and use that? In other words, it would have to be manually set.

the alias is saved as raw data in the key BackupAlias in /Library/Preferences/com.apple.TimeMachine.plist
you can use the CLI tms to get some information

Through a combination of using TMS and removing all special characters from my hostname (now “bob”), it looks like it is working. I am doing an initial backup as we speak, and it did not error out, so I can only assume the timer is running.

Thanks so much, Stefan. I hope I don’t have to bother you with it anymore!

Alright, I have been merrily modifying this script to my heart’s content and am nearly satisfied. I’m having one major snag though, which is actually unrelated to Time Machine: I can’t seem to write to the log file at the end, no matter what I do. Any suggestions, anyone?


-- This script is by Dain Schroeder, with significant help from the user StefanK of the MacScripter.net forums. He is the man.
property backupVolume : "Volumes:Backup of dkschroeder-m-25" -- To backup to a different drive, simply change this property.
set startTime to (get current date) -- This gets the time as of the script being initiated. This will be used later to see how long the script ran.
set currentHost to computer name of (system info) -- This finds the system's hostname, which is used in the Time Machine backup folder.
set backupFolder to (backupVolume & ":" & "Backups.backupdb" & ":" & currentHost) -- This variable simply contains the folder where the backup will be placed. Best not to touch this at all.
do shell script "/System/Library/CoreServices/backupd.bundle/Contents/Resources/backupd-helper" -- Tells Time Machine process, backupd-helper to begin backing up.
repeat
	if not ((do shell script "/bin/ls " & quoted form of POSIX path of backupFolder) contains "inProgress") then exit repeat -- If there is not a .inprogress file in the folder, then move on. 
	delay 0.4 -- Delay 0.4 seconds before repeating; this is to not destroy the computer's resources so much.
end repeat
set endTime to (get current date) -- Ges the time as of the backup finishing.
set duration to endTime - startTime -- Compares the start time to the end time (simple subtraction) and puts the result in the duration variable.
set hrs to duration div hours
set mins to duration div minutes
set secs to duration mod minutes
set today to (do shell script "date '+%d.%m.%Y'")
set finalResult to {"The backup on " & today, " at " & getTimeInHoursAndMinutes(), " took " & hrs & " hours, " & mins & " minutes and " & secs & " seconds." & return} as text
set logName to POSIX file "/Users/dkschroeder-m-25/Documents/TMLog.txt" as file specification

try
	do shell script "/bin ls /Users-dkschroeder-m-25/Documents/TMLog.txt"
on error
	tell application "TextEdit"
		activate
		make new document
		save document 1 in "/Users/dkschroeder-m-25/Documents/TMLog.txt"
	end tell
end try
try
	open for access logName with write permission
	write finalResult to "Users:dkschroeder-m-25:Documents:TMLog.txt" starting at eof
	close access logName
on error
	close access logName
end try

display dialog "The backup took " & hrs & " hours, " & mins & " minutes and " & secs & " seconds." -- Displays our final dialog box with duration information.


--SUBROUTINES!

--I did not design this subroutine; the original author is unknown.
--Get current time in hours and minutes
on getTimeInHoursAndMinutes()
	-- Get the "hour"
	set timeStr to time string of (current date)
	set Pos to offset of ":" in timeStr
	set theHour to characters 1 thru (Pos - 1) of timeStr as string
	set timeStr to characters (Pos + 1) through end of timeStr as string
	
	-- Get the "minute"
	set Pos to offset of ":" in timeStr
	set theMin to characters 1 thru (Pos - 1) of timeStr as string
	set timeStr to characters (Pos + 1) through end of timeStr as string
	
	--Get "AM or PM"
	set Pos to offset of " " in timeStr
	set theSfx to characters (Pos + 1) through end of timeStr as string
	
	return (theHour & ":" & theMin & " " & theSfx) as string
end getTimeInHoursAndMinutes

Hi,

first of all, AppleScript works with HFS paths (colon separated), POSIX paths are only used in shell script.
There is a “shortcut” path to documents folder which is an alias of the documents folder of the current user.
To write to a text file, use the unique file reference number, which will be returned in the open for access line.
If the log file doesn’t exist, it will be created automatically. With UTF8 encoding it can also be read by Console.app
The subroutine can be replaced by one line (do shell script “/bin/date +%l:%M’ '%p”)


-- This script is by Dain Schroeder, with significant help from the user StefanK of the MacScripter.net forums. He is the man.
property backupVolume : "Volumes:Backup of dkschroeder-m-25" -- To backup to a different drive, simply change this property.
set startTime to (get current date) -- This gets the time as of the script being initiated. This will be used later to see how long the script ran.
set currentHost to computer name of (system info) -- This finds the system's hostname, which is used in the Time Machine backup folder.
set backupFolder to (backupVolume & ":" & "Backups.backupdb" & ":" & currentHost) -- This variable simply contains the folder where the backup will be placed. Best not to touch this at all.
do shell script "/System/Library/CoreServices/backupd.bundle/Contents/Resources/backupd-helper" -- Tells Time Machine process, backupd-helper to begin backing up.
repeat
	if not ((do shell script "/bin/ls " & quoted form of POSIX path of backupFolder) contains "inProgress") then exit repeat -- If there is not a .inprogress file in the folder, then move on. 
	delay 0.4 -- Delay 0.4 seconds before repeating; this is to not destroy the computer's resources so much.
end repeat
set endTime to (get current date) -- Ges the time as of the backup finishing.
set duration to endTime - startTime -- Compares the start time to the end time (simple subtraction) and puts the result in the duration variable.
set hrs to duration div hours
set mins to duration div minutes
set secs to duration mod minutes
set today to (do shell script "date '+%d.%m.%Y'")
set finalResult to "The backup on " & today & " at " & (do shell script "/bin/date +%l:%M' '%p") & " took " & hrs & " hours, " & mins & " minutes and " & secs & " seconds."
set logName to ((path to documents folder as text) & "TMLog.txt")
try
	set fileRef to open for access file logName with write permission
	write finalResult & return to fileRef as «class utf8» starting at eof
	close access fileRef
on error
	try
		close access file logName
	end try
end try

display dialog "The backup took " & hrs & " hours, " & mins & " minutes and " & secs & " seconds." -- Displays our final dialog box with duration information.

PS: the time calculation doen’t work reliably

replace


set hrs to duration div hours
set mins to duration div minutes
set secs to duration mod minutes

with


tell duration to set {hrs, mins, secs} to {it div hours, it mod hours div minutes, it mod hours mod minutes div 1}

As always, thank you very much StefanK.

If I may ask, what about the new timer makes it work more reliably than what I initially had? I am not sure I see any difference except that it’s neater code.

the result is the same, but the shell command date is more flexible and can do all the formatting things.
As you use it already for the date string, you can even write (with omitting the today line)


.
set finalResult to "The backup on " & (do shell script "/bin/date +%d.%m.%Y' at '%l:%M' '%p") & " took " & hrs & " hours, " & mins & " minutes and " & secs & " seconds."
.

Is there a way to modify what drive Time Machine will back up to using AppleScript? A Google search showed me a script that accomplishes this, but it uses GUI scripting and is huge and bloated. Is there another way?

I haven’t tested it, but you could change the key BackupAlias in the com.apple.TimeMachine.plist.
Consider that the object type is raw data.

I’ve been working quite a lot on AppleScript, and using this script extensively for some research I’m doing. I thought I’d post the latest version in case anyone wants to do something similar.

Note that the script does not change the destination volume by itself - the user must do this. I looked into what StefanK suggested (about editing the plist), and it was more hassle than it was worth.


set currentHost to computer name of (system info) -- This finds the system's hostname, which is used in the Time Machine backup folder and in network drive access.
set mediaList to {"FireWire", "USB", "Server", "Time Capsule"}
set mediaSelection to (choose from list mediaList with prompt "Please select a backup media." without multiple selections allowed) as text
if mediaSelection is "FireWire" then
	set backupVolume to "Volumes:Firewire TM"
	set logFile to "TMFWLog.txt"
else if mediaSelection is "USB" then
	set backupVolume to "Volumes:USB TM"
	set logFile to "TMUSBLog.txt"
else if mediaSelection is "Server" then
	set backupVolume to "Volumes:Backup of " & currentHost
	set logFile to "TMServerLog.txt"
else if mediaSelection is "Time Capsule" then
	set backupVolume to "Volumes:Backup of " & currentHost
	set logFile to "TMTimeCapsule.txt"
end if
set startTime to (get current date) -- This gets the time as of the script being initiated. This will be used later to see how long the script ran.
set backupFolder to (backupVolume & ":" & "Backups.backupdb" & ":" & currentHost) -- This variable simply contains the folder where the backup will be placed. Best not to touch this at all.
do shell script "/System/Library/CoreServices/backupd.bundle/Contents/Resources/backupd-helper" -- Tells Time Machine process, backupd-helper to begin backing up.
repeat
	if not ((do shell script "/bin/ls " & quoted form of POSIX path of backupFolder) contains "inProgress") then exit repeat -- If there is not a .inprogress file in the folder, then move on. 
	delay 0.9 -- Delay 0.9 seconds before repeating; this is to not destroy the computer's resources so much.
end repeat
set endTime to (get current date) -- Ges the time as of the backup finishing.
set duration to endTime - startTime -- Compares the start time to the end time (simple subtraction) and puts the result in the duration variable.
tell duration to set {hrs, mins, secs} to {it div hours, it mod hours div minutes, it mod hours mod minutes div 1}
set today to (do shell script "date '+%d.%m.%Y'")
set finalResult to "A backup started on " & startTime & " finished at " & endTime & " took " & hrs & " hours, " & mins & " minutes and " & secs & " seconds." -- All our handy log information.
set logName to ((path to documents folder as text) & logFile) -- The script will save to Documents/TMLog.txt by default, but this could be changed.
try
	set fileRef to open for access file logName with write permission -- This opens TMLog.txt with the permissions needed to save to it.
	write finalResult & return to fileRef as «class utf8» starting at eof -- This dumps the info from finalResult into our text file.
	close access fileRef
on error errMsg number errNum
	log "Message: " & errMsg & "; Number: " & errNum
	try
		display dialog "I am about to close the logName access"
		close access file logName
		display dialog "I closed the access to logName"
	end try
end try
display dialog "The backup took " & hrs & " hours, " & mins & " minutes and " & secs & " seconds." -- Displays our final dialog box with duration information.

Sorry for the late reply… I just noticed the date… Why not using similar approach to mine?

Quote:

> >> on isBackupRunning()
> 	try
> 		set status to do shell script "tmutil status | awk -F '= ' '/Running/{gsub(/;/,\"\",$2); print $2}'"
> 		logMessage("Time Machine running status: " & status)
> 		return status is "1"
> 	on error
> 		logMessage("Failed to check Time Machine status.")
> 		return false
> 	end try
> end isBackupRunning