MacOS – Write cron script to open and exit application

applescriptautomationcronmacosterminal

I'm trying to write a script that opens a brand new instance of safari, displays a webpage for 10 minutes, then quits safari.

I think I can follow this Stack Exchange to do steps 1 & 2 of my goal.

For the "display 10 minutes piece," I wasn't sure how to do that except to schedule a separate cron job to quit safari that executes 10 minutes after the first script.

Any idea on how to write a cron script to quit safari? Or to make this process easier? I'm a newbie at cron and would love to learn more.

Thanks!

Best Answer

As an example, the following commands can be used in a shell script to accomplish what you've expressed.

/usr/bin/open -na "/Applications/Safari.app" "https://www.google.com/"
pid=$(/usr/bin/pgrep -xn "Safari")
/bin/sleep 600
/bin/kill $pid

Notes:

Obviously you'd change the value of the URL in the open command.

  • open -na - Assuming another instance of the target app is running, opens a new instance of the target app, and if not, just opens the target app.
  • pgrep -xn - Gets the pid of the newest instance of the target app, so you know which instance to terminate.
    • pid=$(...) - Command Substitution, $(command), allows the output of a command to replace the command name. In this case, assigns the pid of the target app to the variable pid for use as $pid with the kill command.
  • sleep 600 - Sleeps for 10 minutes.
  • kill $pid - Terminate the process by its pid.

I recommend you read the manual pages for open, pgrep, sleep and kill. You can read the manual page for command in Terminal by typing command and then right-click on it and select: Open man Page



cron example:


From the manual page for crontab:

(Darwin note: Although cron(8) and crontab(5) are officially supported under Darwin, their functionality has been absorbed into launchd(8), which provides a more flexible way of automatically executing commands. See launchctl(1) for more information.)

I'm mentioning this because I personally prefer to use launchd over cron as it's the preferred method that Apple endorses.

If you want to use cron, have a look at Scheduling Jobs With Crontab on macOS and crontab guru.

I tested a shell script with the above commands and triggered it both as a cronjob and as a launch agent under macOS Catalina, and it worked for me as coded.

To create the crontab, I did the following in Terminal:

EDITOR=nano crontab -e
  • I use that instead of just crontab -e because I prefer nano over the default vim.

In nano I added the following:

30 18 * * * /usr/local/bin/codetest

Then pressed ^O to save and ^X to close nano.

As set, cron ran the job at 6:30 PM executing the /usr/local/bin/codetest and codetest had a #!/bin/zsh shebang and the commands above, at the start of this answer, in it.

Notes:

I recommend you read the manual pages for cron and crontab. You can read the manual page for command in Terminal by typing command and then right-click on it and select: Open man Page


From Scheduling Jobs With Crontab on macOS:

Setting cron jobs requires a specific format.

* * * * * command
* - minute (0-59)
* - hour (0-23)
* - day of the month (1-31)
* - month (1-12)
* - day of the week (0-6, 0 is Sunday)
command - command to execute

(from left-to-right)

You can also use sites like Crontab.guru to generate cron expressions.



launchd example:


For launchd, have a look at: Creating Launch Daemons and Agents

As a launch agent, in Terminal:

cd "$HOME/Library/LaunchAgents/"
touch com.me.new.instance.safari.plist
open -e com.me.new.instance.safari.plist

I then added the following:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.me.new.instance.safari</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/codetest</string>
    </array>
    <key>RunAtLoad</key>
    <false/>
    <key>StartCalendarInterval</key>
    <array>
        <dict>
            <key>Hour</key>
            <integer>18</integer>
            <key>Minute</key>
            <integer>45</integer>
        </dict>
    </array>
</dict>
</plist>

Saved the document and then back in Terminal:

launchctl load com.me.new.instance.safari

Then at 6:45 PM launchd executed the /usr/local/bin/codetest shell script.


Notes:

I recommend you read the manual pages for launchctl, launchd.plist and launchd. You can read the manual page for command in Terminal by typing command and then right-click on it and select: Open man Page

Once loaded, it will automatically load when you login to your account, so you shouldn't need to do it manually again under normal circumstances. To unload it, use the unload subcommand with the launchctl command.

After unloading it, you can delete the .plist file, if/when you want to undo changes you've made to your system.