Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Quit applications politely from the command line Apps
I often ssh from one Mac to another in order to manage applications on the remote machine. Thus, I find it frustrating that Mac OS X includes no easy way to quit an application politely (allowing the app to save data, clean up after itself, etc.) from the command line. There are command line options that are easy to use, but not nice to applications, and an option that is nice to applications, but not easy to use:
  1. Kill and killall are easy to use, but none of their possible signals will initiate a polite quit of an OS X application. All kill signals either force a quit without saving, or (worse) force a quit without saving and with an error message from the OS. This is because kill deals with processes, not applications.
  2. Osascript can use an Applescript command to initiate a polite quit using the form osascript -e "tell application "AppName" to quit". But it is tedious to write that command on the command line, especially if one has to do this sort of thing more than once in a blue moon.
So I made a way. Now I just type quit AppName on the command line, and the app quits nicely. The quit tool is a bash script, as follows:
#!/bin/bash

#-----------------------------------------------------------
# 
# Quit: quits Mac OS X applications politely
#
# Written by Jon Stovell, July 11, 2009
#
#-----------------------------------------------------------

#-----------------------------------------------------------
# This script takes one or more application names as 
# arguments, and uses osascript to tell each one to quit.
# Unlike kill and killall, this allows applications to save
# files and perform any necessary operations before exiting.
# 
# This script is not case sensitive.
# 
# Note: application names are NOT process names! The 
# application name is the name that Script Editor uses.
# Often the process name and the application name are
# identical, but not always.
#-----------------------------------------------------------

usage()
{
	echo "Usage: `basename $0` [-a] [-p] Application1 \"Application 2\" ..."
	echo ""
	echo "Arguments are the names of one or more applications."
	echo "Arguments are not case sensitive."
	echo "Arguments with spaces should be quoted."
	echo ""
	echo "Options:"
	echo "	-a	Match argument string with any of the application's"
	echo "		name, short name, title, or display name."
	echo "		E.g.: \`quit \"Microsoft Word\"\` and \`quit -a Word\`"
	echo "		will both quit Microsoft Word, because the app calls"
	echo "		itself \"Word\" in the menu bar."
	echo "	-p	Use partial matches (e.g. edit for TextEdit). Prompts"
	echo "		for confirmation."
	echo ""
	exit 65
}

searchall=1
is_contains="is"
while getopts "ap" opt
do
	case $opt in
	a) searchall=0 ;;
	p) is_contains="contains" ;;
	[?]) usage; exit ;;
	esac
	
	shift $(($OPTIND - 1)) # Decrements the argument pointer so it points to next argument. $1 now references the first non option item supplied on the command-line if one exists.
done

if [ -z $1 ]; then usage; fi

for arg in "$@"
do
	if [ searchall=0 ]
	then
		appname=`osascript -e "tell application \"System Events\" to return every application process whose (name $is_contains \"$arg\" or short name $is_contains \"$arg\" or title $is_contains \"$arg\" or displayed name $is_contains \"$arg\")"`
	else
		appname=`osascript -e "tell application \"System Events\" to return every application process whose name $is_contains \"$arg\""`
	fi
	
	if [[ -n $appname && $appname != *", "* ]] # found 1 matching application
	then 
		if [[ $is_contains == is ]]
		then
			osascript -e "ignoring application responses" -e "tell application \"$appname\" to quit with saving" -e "end ignoring"
		else
			echo "Choose the application to quit:"
			
			eval set $appname # this allows multi-word selections in select
			select appname in "$@"
			do
				osascript -e "ignoring application responses" -e "tell application \"$appname\" to quit with saving" -e "end ignoring"
				break
			done
		fi
			
	elif [[ -z $appname ]] # found no matching application
	then
		echo "No running application matches \"$arg\""
	
	elif [[ $appname == *", "* ]] # found >1 matching applications.
	then
		appname=`echo $appname | sed -e 's/^/\"/' -e 's/$/\"/' -e 's/, /\" \"/'`
		echo "\"$arg\" matches multiple applications."
		echo "Choose the application to quit:"
		
		eval set $appname # this allows multi-word selections in select
		select appname in "$@"
		do
			osascript -e "ignoring application responses" -e "tell application \"$appname\" to quit with saving" -e "end ignoring"
			break
		done
	fi
done
To use the above code, you'll need to copy, paste, save, and make executable ... or you can simply grab quit from MacUpdate and drag it to its final destination.

This script essentially executes the osascript command, but without requiring all the verbiage. Originally I tried just putting a one line addition into ~/.profile to do this, but ran into some limitations that made a full-fledged bash script more appropriate.

This script takes one or more application names as arguments, and uses osascript to tell each one to quit. The arguments are not case sensitive, so quit textedit will work. App names with spaces should be quoted or have the spaces escaped. If more than one matching application is found, the user will be prompted to select the correct one from a list. This prompt always occurs with the -p option (see below). The program has two options:
  • -a will match with all possible versions of an app's name, including its name, short name, title, or display name. (e.g. quit "Microsoft Word" and quit -a Word will both quit Microsoft Word, because the app calls itself "Word" in the menu bar.
  • -p tells the script to use partial matches to find the application to quit. This option always prompts for confirmation before quitting the app. (e.g. if TextEdit is running, quit -p edit will prompt the user whether they want to quit TextEdit.)
[robg adds: This is a more-thorough and enhanced alternative to a simple script that was posted here years ago. Note that this version only works in 10.5, and the MacUpdate link will always have the newest code, so that's your best bet. I mirrored the code here just in case the original ever vanishes.]
    •    
  • Currently 2.55 / 5
  You rated: 3 / 5 (11 votes cast)
 
[25,782 views]  

Quit applications politely from the command line | 11 comments | Create New Account
Click here to return to the 'Quit applications politely from the command line' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Quit applications politely from the command line
Authored by: zacht on Aug 26, '09 08:13:56AM

Very nice, thank you!



[ Reply to This | # ]
Quit applications politely from the command line
Authored by: lincd0 on Aug 26, '09 11:50:57AM

This script is well done and may be useful to some people. But automatically overwriting open files when you quit an application remotely isn't always "polite." Your cat might have been sleeping on the keyboard while you were away from your desk. If you send a kill signal to an application, at least you can be sure that no stored data has been overwritten.



[ Reply to This | # ]
Quit applications politely from the command line
Authored by: Sesquipedalian on Aug 27, '09 07:08:29AM

That's a good point. Maybe I'll put out a new version with an option not to save.



[ Reply to This | # ]
Quit applications politely from the command line
Authored by: Sesquipedalian on Aug 28, '09 10:17:49AM

I've just uploaded version 1.1 which includes an -n option that tells the app not to save changes.



[ Reply to This | # ]
Quit applications politely from the command line
Authored by: cran on Aug 27, '09 06:45:56AM

Is it really such that OS X applications (which ARE processes, otherwise they wouldn't appear in "ps" listings) do not catch SIGTERM/SIGINT and such to shut down cleanly? Really!?

To me this seems hard to imagine. But then I don't know better.



[ Reply to This | # ]
Quit applications politely from the command line
Authored by: Sesquipedalian on Aug 27, '09 07:05:36AM
Yes, really. For example, the command one might expect to work as desired, killall -QUIT TextEdit, produces an error message saying "The application TextEdit quit unexpectedly." By all means feel free to play around with the various kill signals, but from what I can find, none of them perform the same way as pressing ⌘Q when using the application.

Obviously every application has a process at its core, so you will see at least one process for each application, but an application is more than just a process.

[ Reply to This | # ]

Quit applications politely from the command line
Authored by: cran on Aug 27, '09 11:32:19PM

I just tried it: "killall -TERM TextEdit" works as I expect, producing no error message but just telling TextEdit to die asap. "killall -QUIT" indeed does behave different. But SIGTERM is what's usually sent if you do not give an explicit signal.

On the other hand it's right that on SIGTERM TextEdit won't ask you for saving your half-finished document, it will discard all changes. But that's what I expect if I say "dear program, please terminate asap".

Now I think I understand your hint and what it's for, I got it wrong after the first read. But I am still pretty sure that most OS X programs (application or not) do handle SIGTERM and do some clean up before exiting.



[ Reply to This | # ]
Quit applications politely from the command line
Authored by: Sesquipedalian on Aug 28, '09 10:38:43AM
Perhaps this example will help further illuminate the matter: I use an application called Journler that updates its internal database as part of its quitting procedure. killall Journler kills the app without triggering that procedure.

For further reading, you might be interested in this.

[ Reply to This | # ]

Fast User Switching
Authored by: wkessinger on Sep 19, '09 07:31:28AM

This script was exactly what I was looking for. I am running an iTunes 9 Home Sharing server on an alternate account under Fast User Switching. This is serving the iTunes "master library" for my family. The iMac it runs on is also a family computer for the kids.

Of course, I frequently need to administer the master library to keep it synced with purchases that have been loaded into individual users' libraries. With this script I'm able to ssh into the iMac FUS account, close down iTunes, then open the same iTunes library on my laptop without interrupting anyone's iMac session.

If the current iMac user is running a second copy of iTunes, this script doesn't seem to see it; it closes down the FUS iTunes session without asking me to choose between the processes. The script does generate a warning message (twice):

_RegisterApplication(), FAILED TO establish the default connection to the WindowServer, _CGSDefaultConnection() is NULL.

but this doesn't seem to interfere with its successful execution.



[ Reply to This | # ]
Quit applications politely from the command line
Authored by: Sesquipedalian on May 18, '10 04:11:40PM
Just a note that version 1.3 is available.

Usage: quit [-a] [-p] [-s|n] application names

Arguments are the names of one or more applications.
Arguments are not case sensitive.
Arguments with spaces should be quoted.

Options:

-a Match argument string with any of the application's name, displayed name, short name, or title. E.g.: `quit "Microsoft Word"` and `quit -a Word` will both quit Microsoft Word, because the app calls itself "Word" in the menu bar.

-p Use partial matches (e.g. edit for TextEdit). Prompts for confirmation.

-s Attempt to save modified files when quitting. Overrides any previous -n option.

-n Do not attempt to save modified files when quitting. Overrides any previous -s option.

If neither the -s or -n options are specified, quit will try to detemine if any documents require saving, and if necessary will ask the user whether to save or not.

[ Reply to This | # ]

Quit applications politely from the command line
Authored by: bhall7 on Dec 09, '10 03:49:47PM

This script is super useful and helped me schedule cron jobs on a kiosk running Snow Leopard. It was the only thing that would let me automate the closure of an OpenOffice Impress presentation (although I had to execute "quit" twice while in a full-screen presentation for some reason). On another note, where should I copy custom scripts to so that they can be executed globally? Or how do I modify the included path to include a folder with custom scripts? Thanks!



[ Reply to This | # ]