Estoy intentando producir un comando de shell basado en Applescript que le indique a la aplicación Vista previa de Mac OS X que cierre una ventana en particular.
#!/bin/sh
osascript <<EOF
tell application "Preview"
close "$1"
end tell
EOF
Pero esto no funciona: aparece el mensaje de error.
25:52: execution error: Preview got an error: "musixdoc.pdf" doesn’t understand the close message. (-1708)
Pregunta relacionada:¿Cómo cierro una aplicación OS X desde la línea de comando usando un alias definido en mi .bash_profile?
Respuesta1
Conseguir que Preview.app acepte comandos de AppleScript
De forma predeterminada, AppleScripting Preview no funcionará porque a Preview le falta el diccionario necesario. Para solucionar este problema, consulteLa respuesta de Lauri aquí., que explica la configuración NSAppleScriptEnabled
de Preview.app.
Salga de Preview.app, luego abra una terminal e ingrese:
sudo defaults write /Applications/Preview.app/Contents/Info NSAppleScriptEnabled -bool true
sudo chmod 644 /Applications/Preview.app/Contents/Info.plist
sudo codesign -f -s - /Applications/Preview.app
Cerrar una ventana desde una aplicación
1) Por índice de ventana o nombre de la ventana
El comando para cerrar una ventana de cualquier aplicación con nombre sería algo como esto:
tell application "Preview" to close window 1
… o si desea cerrar una ventana de documento con nombre, por ejemplo foo.jpg
:
decirle a la aplicación "Vista previa" que se cierre (todas las ventanas cuyo nombre sea "foo.jpg")
Entonces, en tu script de shell sería:
#!/bin/sh
osascript <<EOF
tell application "Preview"
close (every window whose name is "$1")
end tell
EOF
Aquí, el primer argumento que se pasa al script es el nombre de la ventana que desea cerrar, por ejemplo ./quit.sh foo.jpg
. Tenga en cuenta que si su archivo contiene espacios, debe citar el nombre del archivo, por ejemplo ./quit.sh "foo bar.jpg"
.
O si desea cerrar ventanas arbitrarias desde cualquier aplicación, use esto:
#!/bin/sh
osascript <<EOF
tell application "$1"
close (every window whose name is "$2")
end tell
EOF
Aquí usarías, ./quit.sh Preview foo.jpg
por ejemplo.
2) Por nombre de archivo
Si desea cerrar una ventana que pertenece a un determinado documento, pero proporciona el nombre del archivo, necesita algo más. Esto se debe a que un PDF de varias páginas podría mostrarse como foo.pdf (Page 1 of 42)
, pero solo querrás pasar foo.pdf
al AppleScript.
Aquí iteramos a través de las ventanas y comparamos los nombres de archivos con el argumento pasado al 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
EOF
Ahora puedes simplemente llamar ./quit.sh foo.pdf
. De forma generalizada, para todas las aplicaciones con ventanas de documentos con nombre, sería:
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
Advertencia: Preview.app de cierre automático
Preview.app es una de estas aplicaciones que se cierra automáticamente una vez que se cierra la ventana del último documento. Lo hace para ahorrar memoria y "limpiar". Para deshabilitar este comportamiento, ejecute lo siguiente:
defaults write -g NSDisableAutomaticTermination -bool TRUE
Por supuesto, para deshacer eso, cambie TRUE
a FALSE
.
Usar funciones en lugar de scripts
Finalmente, sugeriría poner sus scripts en una función que siempre esté disponible en su shell. Para hacer esto, agregue los scripts a su archivo ~/.bash_profile
. Cree este archivo si no existe.
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
}
Una vez que guarde su perfil de bash y reinicie el shell, podrá llamar cw Preview foo.pdf
desde cualquier lugar.
Respuesta2
La respuesta de slhck parece buena y completa.Cuidado, ejecutando la tercera línea de código.:
sudo codesign -f -s - /Applications/Preview.app
"parece" haber provocado que la Vista previa se bloquee en cada inicio con lo siguiente:
Application Specific Information:
XPC domain creation failed: The code signature is not valid: The operation couldn’t be completed. (OSStatus error -67061.)
Según el manual de diseño de código, eso -f
es forzar la 'señal de código para reemplazar la firma existente' y es -s
'firmar el código en la ruta dada'... en este caso-
Aparentemente, la Vista previa ahora está firmada incorrectamente y es inutilizable. :(