1

I'd like to run a script to close all apps currently open in my doc. Figured out how to do with with the following script, where APPLICATIONNAME is the name of the app in the dock currently open

osascript -e 'quit app "APPLICATIONNAME"'

Any ideas on how to expand this command to encompass all apps open inside the doc?

Ideally we'd avoid using a killall flavor of script. As force closing running apps in bulk will pose risks in some circumstances

Nick Sarafa
  • 986
  • 10
  • 16

2 Answers2

3

Firstly there is no terse solution to achieve this using osascript as described in your question. osascript by itself simply doesn't provide the options/arguments necessary to fulfil the logic of your requirement.

However, the following bash shell script (.sh) avoids using killall and will prompt the user to save any unsaved changes to document(s) before closing/quitting the application. (This is very similar to how the user is prompted to save any unsaved changes when shutting down the computer):

close-apps.sh

#!/bin/bash

# Creates a comma-separated String of open applications and assign it to the APPS variable.
APPS=$(osascript -e 'tell application "System Events" to get name of (processes where background only is false)')

# Convert the comma-separated String of open applications to an Array using IFS.
# http://stackoverflow.com/questions/10586153/split-string-into-an-array-in-bash
IFS=',' read -r -a myAppsArray <<< "$APPS"

# Loop through each item in the 'myAppsArray' Array.
for myApp in "${myAppsArray[@]}"
do
  # Remove space character from the start of the Array item
  appName=$(echo "$myApp" | sed 's/^ *//g')

  # Avoid closing the "Finder" and your CLI tool.
  # Note: you may need to change "iTerm" to "Terminal"
  if [[ ! "$appName" == "Finder" && ! "$appName" == "iTerm" ]]; then
    # quit the application
    osascript -e 'quit app "'"$appName"'"'
  fi
done

Note: In the following line of code we avoid closing the Finder and the CLI tool that the command will be run via. You will probably need to change "iTerm" to "Terminal", or to whatever the name of your CLI tool is:

if [[ ! "$appName" == "Finder" && ! "$appName" == "iTerm" ]]; then

Making close-apps.sh executable

As explained in this answer you will need to make the close-apps.sh executable before it can be run. To do this enter the following via your CLI:

$ chmod +x /path/to/close-apps.sh

(The /path/to/close-apps.sh part should be replaced with your path according to where the script is saved)


Running close-apps.sh via the CLI.

You run the shell script by entering the following into the CLI:

$ /path/to/close-apps.sh

(Again, the /path/to/close-apps.sh part should be replaced with your path according to where the script is saved)


Running close-apps.sh via an Applescript.

The shell script can also be executed via an AppleScript application simply by double-clicking instead of entering a command via the CLI.

To do this you'll need to:

  1. Open the AppleScript Editor application, which can be found inside the Applications/Utilities/ folder.

  2. Enter the following code:

on run
    do shell script "/path/to/close-apps.sh"
    quit
end run

(Again, the /path/to/close-apps.sh part should be replaced with your path according to where the .sh script is saved)

  1. Save the Applescript and chose File Format: Application via the save dialog. Let's call it closeApps.app.

  2. Finally, the following line of code in the close-apps.sh script should be changed from this:

if [[ ! "$appName" == "Finder" && ! "$appName" == "iTerm" ]]; then

... to this:

if [[ ! "$appName" == "Finder" && ! "$appName" == "closeApps" ]]; then

Note The filename of the Applescript (closeApps) replaces iTerm (or Terminal).

  1. To close all applications open in the dock you simply double click the closeApps application icon.
Community
  • 1
  • 1
RobC
  • 22,977
  • 20
  • 73
  • 80
  • This is excellent! Is there a way to create an array of apps it shouldn't close? Or to force specific apps to quit? Apparently MS Teams doesn't play nice and it just stays open. Not the end of the world, but a force option would be nice. – DWShore Sep 09 '20 at 14:42
  • You can specify apps that should _not_ be closed by extending the `if` condition in the shell script. This [example](https://paste.ee/p/xSJcC) _(lines #20 and #21)_ additionally excludes both `firefox` and `Safari` from being closed too. If you have to resort to force quitting then consider utilizing [`killall`](https://ss64.com/osx/killall.html) in the shell script, however it does risk loosing unsaved changes (hence why I avoided using it in this solution). – RobC Sep 09 '20 at 16:51
  • Great script! Only had a problem with VS Code. It doesn't work for it because the "process name" (Electron) is different for the "app name" (Code). Solved it by replacing that word in the apps array. Add this line right before the for loop: myAppsArray=("${myAppsArray[@]/Electron/Code}") To have in mind: If you are running any other application which name is Electron it won't close it. – manna Oct 13 '22 at 05:40
1

Try this

tell application "System Events"
    set appList to the name of every process whose background only is false
end tell
repeat with theApp in appList
    try
        tell application theApp to quit
    end try
end repeat
a2bk
  • 301
  • 2
  • 8