You know how sometimes a blog or web form eats your comment or you lose some text and break your undo history or something and you wish you could rewind and see what was on your screen some minutes or hours ago? I made a script to do that that has saved my butt more than once. It’s also handy for checking things like what time you left the office.
Here it is:
#!/bin/bash
# By dreev, written maybe 2017, last edited 2024-08-10
#-------------------------------------------------------------------------------
# Instructions:
# Cron this like so to save screenshots aka screencaps every minute:
# * * * * * /full/path/to/this/script.sh
# Next go to macOS Privacy & Security settings and give Full Disk Access to:
# /bin/bash
# /usr/sbin/cron
# Also in Privacy & Security settings, give Screen & System Audio Recording to:
# /usr/sbin/cron
# Screenshots older than 24 hours will get overwritten by new ones and the whole
# collection should be at most a gigabyte or so if the jpeg quality is kept low.
# Filenames are eg screen1cap-13-59.jpg for a screencap of display 1 at 1:59pm.
#-------------------------------------------------------------------------------
jq=20; # jpeg quality (20 seems always readable, 10 not always for small fonts)
scap="/usr/sbin/screencapture"; # standard macOS screenshot tool
mogr="/opt/homebrew/bin/mogrify"; # part of ImageMagick for transforming images
path="/Users/dreeves/tmp/screenshots"; # where all the screenshots live
t=$(/bin/date +%s) # current time as unixtime
hm=$(/bin/date +%H-%M); # eg "19-59" when it's 7:59pm
# get the number of connected, online displays (not needed currently)
#n=`/usr/sbin/system_profiler SPDisplaysDataType | grep -c 'Online: Yes'`;
f1="$path/screen1cap-$hm.jpg"
f2="$path/screen2cap-$hm.jpg"
f3="$path/screen3cap-$hm.jpg"
# grab a screenshot for every monitor (up to 3 currently; add more to taste)
$scap -x -d -r -T0 -tjpg $f1 $f2 $f3
/bin/sleep 1 # make sure the screencapture is done
t1=$(/bin/date -r $f1 +%s)
t2=$(/bin/date -r $f2 +%s)
t3=$(/bin/date -r $f3 +%s)
# drastically reduce the file sizes (for the ones just now created)
if [ $t1 -ge $t ] ; then $mogr -quality $jq $f1 &> /dev/null ; fi
if [ $t2 -ge $t ] ; then $mogr -quality $jq $f2 &> /dev/null ; fi
if [ $t3 -ge $t ] ; then $mogr -quality $jq $f3 &> /dev/null ; fi
Separately, here’s a bit of Wolfram code to touch all possible 24*60*numscreens
files, if you don’t want missing files when the display is off.
It’s safe to run any time — it only touches files that don’t exist.
And the only reason to bother is that it can be handy for treating the screenshot timestamps as quantified-self data, like, “I’ve never been awake at 4am since I started running this on such-and-such date”.
path = "~/tmp/screenshots/";
numscreens = Length[SystemInformation["Devices", "ScreenInformation"]];
numcreated = 0;
prn["Screens: ", numscreens];
each[s_, Range[1, numscreens],
each[h_, Range[0, 23],
each[m_, Range[0, 59],
f = cat[path, "screen", s, "cap-", If[h < 10, "0", ""], h, "-",
If[m < 10, "0", ""], m, ".jpg"];
If[! FileExistsQ[f],
numcreated++;
CreateFile[f];
SetFileDate[f, DateObject[{1970, 1, 1}]]]]]];
prn["Files created: ", numcreated];