This is a revival of an old project of mine, rewritten
for v2.0 with some updates for recent versions of macOS and
with the addition of some command line flags that make
scripting easier. This code is based on
a post by Jean-David Gadina, on which I’ve
elaborated.
beengone is a (macOS-only) CLI tool that tests how long a
Mac has gone without user input (keyboard or
mouse/trackpad). It detects any movement or keypress,
including modifier keys. Run without arguments, it outputs
the number of seconds the machine has been idle.
Current version: 2.0.8
You can print the seconds idle with no newline using -n,
simulate input with -i, resetting the idle timer.
For ease of scripting, there’s a -m/--minimum=XXX option
which sets a minimum number of seconds required to pass the
condition. If the idle time is less than the minimum,
beengone returns an error code of 1. If the minimum is met,
it exits successfully with an error code of 0.
You can also pause scripts until a limit with the
-w/--wait=XXX flag, avoiding having to loop and check exit
codes. -w will always exit 0 once the limit is reached.
Both -m and -w accept either integer values in seconds,
or strings in the format “Xd Xh Xm Xs”, representing days,
hours, minutes, and seconds. Any combination can be used,
and spaces aren’t required, e.g. -w 2m30s.
Usage: beengone [options]
Print the system idle time in seconds.
Options
-n, --no-newline print idle seconds without newline
-m, --minimum=<str>test for minimum idle time in seconds, exit 0 or 1 based on
condition, accepts strings
like "5h 30m" or "1d12h"
-w, --wait=<str>wait until the system has been
idle for the specified number of
seconds, accepts strings
like "5h 30m" or "1m30s"
-i, --input simulate user input
Other
-h, --help show this help message and exit
-d, --debug print debugging info
-v, --version show version and exit
#! /bin/bashgone(){if[[-n$1]];thenTIME=$1# loop indefinitely# > could also use --wait flag to wait for the user to be# > gone instead of loopingwhiletrue;do# use the --minimum flag to generate an exit code# based on a minimum thresholdbeengone-m"$TIME"&>/dev/null
# get the exit coderetVal=$?# if the exit code is 0, the user has been gone# for the specified timeif[$retVal-eq0];then# if a command was specified, execute itif[[-n$COMMAND]];theneval"$COMMAND"exit$?fibreakfidoneelseecho"Missing argument: TIME"exit1fiexit1}POSITIONAL_ARGS=()display_help(){echo"Usage: ifgone [OPTIONS] TIME"echoecho"TIME (required) is the time to wait for the user to be gone"echo"TIME can be formatted as XXX (seconds), XXXm (minutes), XXXh (hours), XXXd (days)"echoecho"OPTIONS:"echo" -c, --command Command to execute upon success"echo" -h, --help Display this help message"}while[[$#-gt0]];docase$1in-h|--help)display_help
;;-c|--command)COMMAND=$2shiftshift;;-*|--*)echo"Unknown option $1"exit1;;*)POSITIONAL_ARGS+=("$1")# save positional argshift# past argument;;esacdoneset--"${POSITIONAL_ARGS[@]}"# restore positional parametersgone"$1"
#!/bin/bash# Example script to test the beengone command# Loops while checking idle time with a minimum threshold before executin a command# Works while screen saver is runningopen/System/Library/CoreServices/ScreenSaverEngine.app
whiletrue;dobeengone-m3s
if[[$?-eq0]];thenosascript-e'tell application "ScreenSaverEngine" to quit'breakfisleep1done# Pause a timer when there's no activity for a set timetimer=-1
whiletrue;dobeengone-m5m
if[[$?-eq0]];then# Could be `shortcuts` or any commandresult=$(osascript-e"display dialog "EndTimer?" buttons {"END", "CONTINUE"} default button "CONTINUE""2>/dev/null)if[[$result=~END]];thenbreakfifisleep1timer=$((timer+1))doneosascript-e"display alert \"Timer: $timer seconds\" message \"Timer Ended\" giving up after 5"# Using the --wait/-w flag to wait for a set time before executing a command# This avoids the need to loop and check the idle timebeengone-w5s
osascript-e"display alert \"Waited 5 seconds\" message \"Wait Ended\" giving up after 5"