I’m trying to produce an Applescript-based shell command that tells the Preview application from Mac OS X to close a particular window.
#!/bin/sh
osascript <<EOF
tell application "Preview" close "$1"
end tell
EOFBut this doesn’t work : I get the error message
25:52: execution error: Preview got an error: "musixdoc.pdf" doesn’t understand the close message. (-1708)Related question: How do I close an OS X application from the command line using a alias defined in my .bash_profile?
22 Answers
Getting Preview.app to accept AppleScript commands
By default, AppleScripting Preview won't work because Preview is missing the necessary dictionary. To fix this, check Lauri's answer here, which explains setting NSAppleScriptEnabled for Preview.app.
Quit Preview.app, then open a terminal and enter:
sudo defaults write /Applications/ NSAppleScriptEnabled -bool true
sudo chmod 644 /Applications/
sudo codesign -f -s - /Applications/Preview.appClosing a window from an application
1) By window index or name of the window
The command to close a window of any named application would be something like this:
tell application "Preview" to close window 1… or if you want to close a named document window, e.g. foo.jpg:
tell application "Preview" to close (every window whose name is "foo.jpg")
So, in your shell script that'd be:
#!/bin/sh
osascript <<EOF
tell application "Preview" close (every window whose name is "$1")
end tell
EOFHere, the first argument passed to the script is the name of the window you want to close, e.g. ./quit.sh foo.jpg. Note that if your file contains spaces, you have to quote the filename, e.g. ./quit.sh "foo bar.jpg".
Or if you want to close arbitrary windows from any application, use this:
#!/bin/sh
osascript <<EOF
tell application "$1" close (every window whose name is "$2")
end tell
EOFHere, you'd use ./quit.sh Preview foo.jpg for example.
2) By file name
If you want to close a window that belongs to a certain document, but supplying the file name, you need something else. This is because a multi-page PDF could be displayed as foo.pdf (Page 1 of 42), but you'd just want to pass foo.pdf to the AppleScript.
Here we iterate through the windows and compare the filenames against the argument passed to the script:
osascript <<EOF
tell application "Preview" set windowCount to number of windows repeat with x from 1 to windowCount set docName to (name of document of window x) if (docName is equal to "$1") then close window x end if end repeat
end tell
EOFNow you can simply call ./quit.sh foo.pdf. In a generalized fashion, for all apps with named document windows, that'd be:
osascript <<EOF
tell application "$1" set windowCount to number of windows repeat with x from 1 to windowCount set docName to (name of document of window x) if (docName is equal to "$2") then close window x end if end repeat
end tell
EOFCaveat: Auto-closing Preview.app
Preview.app is one of these applications that automatically quits once its last document window is closed. It does that in order to save memory and "clean up". To disable this behavior, run the following:
defaults write -g NSDisableAutomaticTermination -bool TRUEOf course, to undo that, change TRUE to FALSE.
Using functions instead of scripts
Finally, I'd suggest putting your scripts into a function that is always available in your shell. To do this, add the scripts to your ~/.bash_profile. Create this file if it doesn't exist.
cw() {
osascript <<EOF
tell application "$1" set windowCount to number of windows repeat with x from 1 to windowCount set docName to (name of document of window x) if (docName is equal to "$2") then close window x end if end repeat
end tell
EOF
}Once you save your bash profile and restart the shell, you can call cw Preview foo.pdf from everywhere.
The answer by slhck looks good and thorough. Beware, executing the third code line:
sudo codesign -f -s - /Applications/Preview.app'seems' to have caused Preview to crash on every launch with the following:
Application Specific Information:
XPC domain creation failed: The code signature is not valid: The operation couldn’t be completed. (OSStatus error -67061.)According to the codesign manual, that -f is forcing 'code sign to replace and existing signature' and the -s is to 'sign the code at the path given' … in this case -
Apparently, Preview is now incorrectly signed and unusable. :(