46

The Time Machine control panel gives information on in-progress backups. For example

enter image description here

Is there a way to get the information from the command line?

Matteo
  • 8,855

6 Answers6

67

While the backup is running, detailed information gan be gained by

tmutil status

which should return something like this:

Backup session status:
{
    BackupPhase = Copying;
    ClientID = "com.apple.backupd";
    DateOfStateChange = "2014-12-18 14:14:21 +0000";
    DestinationID = "B4AF88-5AD5-49BE-B254-650B44E20499";
    DestinationMountPoint = "/Volumes/TimeMachine";
    Percent = "0.852581430477103";
    Progress =     {
        TimeRemaining = 0;
        "_raw_totalBytes" = 38596759;
        bytes = 36563200;
        files = 480;
        totalBytes = 42456434;
        totalFiles = 480;
    };
    Running = 1;
    Stopping = 0;
    "_raw_Percent" = "0.9473127005301144";
}

If you only care for the percentage, try the following (looks ugly, works only if there is a percentage to display):

tmutil status | awk '/_raw_Percent/ {print $3}' | grep -o '[0-9].[0-9]\+\(e-[0-9]\+\)\?' | awk '{print $1*100}'

Updated 10 years later:

To better parse tmutil's plist output using builtin methods, you need to remove the initial line with tail and then convert it to JSON via plutil:

tmutil status | tail -n +2 | plutil -convert json -o - -- - | jq

Note that the pipe into jq is given here only for nicer formatting. To directly access individual values, instead use e.g.: | jq '.["BackupPhase"]'

Asmus
  • 7,585
10

To get only the percentage value:

tmutil status | LC_NUMERIC="C" awk -F'"' '/_raw_Percent/ {print $4 * 100}'
grg
  • 201,078
donnie
  • 101
  • Thank you! I used this with the watch command like this watch -n 2 "tmutil status | LC_NUMERIC='C' awk -F'\"' '/_raw_Percent/ {print \$4 * 100}'" to get an update e.g., every 2 seconds. – intagli Oct 23 '23 at 23:58
1

I managed to make a simple script from the accepted answer.

tmstatus () {
  eval $(tmutil status | grep -E '[^}];$' | perl -p -e 's/^\s+[\"]*//g;' -e 's/[\"]*\s+\=\s+/=/g') || (echo "Something get wrong..." && return 1)

if [[ $Running -eq 1 ]] then export LC_NUMERIC="en_US.UTF-8" [[ $BackupPhase == "Copying" ]] && Percent=$(printf '%0.2f%%' bc <<< $Percent*100) && echo "${DateOfStateChange} ${BackupPhase} backup to ${DestinationMountPoint}: ${totalFiles} files - ${Percent} (~$((${TimeRemaining:-0}/60)) min." || echo "${DateOfStateChange} ${BackupPhase} (Destination ${DestinationID})." else echo "TimeMachine backup is not running." fi }

Atika
  • 313
1

Maybe a bit more complicated but also more practical for processing, the following command will write the progress status into a plist file and convert it into json:

tmutil status | grep -v 'Backup session status' > a.plist; plutil -convert json a.plist

Json can be parsed more easily to extract various information.

0

I used @Atika's very helpful script but sometimes got errors like

bash: 26520.80484282512/60: syntax error: invalid arithmetic operator (error token is ".80484282512/60")

So I made a slight tweak to pass that division operation to bc and now it works reliably (caveat: for me!):

Before:

(~$((${TimeRemaining:-0}/60)) min."

After:

(~$(bc <<< ${TimeRemaining:-0}/60) min.)

Updated Script:

tmstatus () {
  eval $(tmutil status | grep -E '[^}];$' | perl -p -e 's/^\s+[\"]*//g;' -e 's/[\"]*\s+\=\s+/=/g') || (echo "Something get wrong..." && return 1)

if [[ $Running -eq 1 ]] then export LC_NUMERIC="en_US.UTF-8" [[ $BackupPhase == "Copying" ]] && Percent=$(printf '%0.2f%%' $(bc <<< $Percent*100)) && echo "${DateOfStateChange} ${BackupPhase} backup to ${DestinationMountPoint}: ${totalFiles} files - ${Percent} (~$(bc <<< ${TimeRemaining:-0}/60) min.)" || echo "${DateOfStateChange} ${BackupPhase} (Destination ${DestinationID})." else echo "TimeMachine backup is not running." fi }

Giacomo1968
  • 5,623
Joel P.
  • 101
0

I did a script for this that can be executed from Terminal.

https://github.com/fedekrum/Mac-Time-Machine-status

#!/bin/bash

Check if we're root and re-run if not.

if [ $(id -u) -ne 0 ]; then echo "Script not running as root, trying to elevate to root..." sudo bash "$0" "$@" exit $? fi clear

Get the PID of the process "/System/Library/CoreServices/backupd.bundle/Contents/Resources/backupd"

PID=$(ps -ef | awk '$8=="'/System/Library/CoreServices/backupd.bundle/Contents/Resources/backupd'" {print $2}')

If the process is not found, it alerts the user and quits

if [ -z "$PID" ]; then echo "The process '/System/Library/CoreServices/backupd.bundle/Contents/Resources/backupd' is not running" exit 1 fi clear

Loop to continuously check the status

while true; do echo -e "\033[H"

# Check if the output of &quot;tmutil status&quot; contains &quot;ThinningPreBackup&quot;
if tmutil status | grep -q &quot;ThinningPreBackup&quot;; then
    # If it does, run &quot;lsof -p $PID&quot; and show the last line as the status
    echo
    printf &quot;$(lsof -p $PID | tail -n 1 | awk -F'/[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{6}' '{print substr($2, 2)}')\n&quot;
else
    # If it doesn't, show the result of &quot;tmutil status&quot;
    echo
    printf &quot;$(tmutil status)\n&quot;
fi

# Get the width of the terminal

width=$(tput cols)

Generate a line filled with spaces

line=$(printf '%*s' $width)

Do it for three lines

for i in {1..3}; do # Print a carriage return and the line of spaces, effectively overwriting the current line with spaces echo -en "\r$line\r"

# Move to the next line
echo

done

# Wait for 10 seconds before the next round
for i in {10..1}; do
  echo -e &quot;\033[H&quot;
  echo &quot;$i &quot;
  sleep 1
done

done

nohillside
  • 100,768
FedeKrum
  • 101
  • 1
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center. – Community Jul 31 '23 at 09:46
  • Link only answers are not appreciated, especially if your GitHub account goes, then your answer is worthless. At least provide a copy of the script here (like other answers do), and explain it's workings. – Andy Griffiths Jul 31 '23 at 09:49