9

Я пытаюсь создать команду оболочки на основе Applescript, которая сообщает приложению Preview из Mac OS X закрыть определенное окно.

#!/bin/sh

osascript <<EOF
tell application "Preview"
   close "$1"
end tell
EOF

Но это не работает: я получаю сообщение об ошибке

25:52: execution error: Preview got an error: "musixdoc.pdf" doesn’t understand the close message. (-1708)

Связанный вопрос: Как закрыть приложение OS X из командной строки, используя псевдоним, определенный в моем .bash_profile?

2 ответа2

10

Получение Preview.app для принятия команд AppleScript

По умолчанию предварительный просмотр AppleScripting не будет работать, поскольку в предварительном просмотре отсутствует необходимый словарь. Чтобы это исправить, проверьте ответ Лаури здесь, который объясняет настройку NSAppleScriptEnabled для Preview.app.

Выйдите из Preview.app, затем откройте терминал и введите:

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


Закрытие окна из приложения

1) По индексу окна или названию окна

Команда для закрытия окна любого именованного приложения будет выглядеть примерно так:

tell application "Preview" to close window 1

... или если вы хотите закрыть именованное окно документа, например, foo.jpg:

tell application "Preview" to close (every window whose name is "foo.jpg")

Итак, в вашем сценарии оболочки это будет:

#!/bin/sh
osascript <<EOF
tell application "Preview"
  close (every window whose name is "$1")
end tell
EOF

Здесь первым аргументом, передаваемым скрипту, является имя окна, которое вы хотите закрыть, например ./quit.sh foo.jpg . Обратите внимание, что если в вашем файле есть пробелы, вы должны указать имя файла, например ./quit.sh "foo bar.jpg" .

Или, если вы хотите закрыть произвольные окна из любого приложения, используйте это:

#!/bin/sh
osascript <<EOF
tell application "$1"
  close (every window whose name is "$2")
end tell
EOF

Здесь вы можете использовать ./quit.sh Preview foo.jpg например.

2) По имени файла

Если вы хотите закрыть окно, принадлежащее определенному документу, но указав имя файла, вам нужно что-то еще. Это связано с тем, что многостраничный PDF-файл может отображаться как foo.pdf (Page 1 of 42) , но вы просто хотите передать foo.pdf в AppleScript.

Здесь мы перебираем окна и сравниваем имена файлов с аргументом, переданным скрипту:

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

Теперь вы можете просто позвонить ./quit.sh foo.pdf . Обобщенно, для всех приложений с именованными окнами документов это будет:

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


Предостережение: автоматическое закрытие Preview.app

Preview.app - одно из этих приложений, которое автоматически закрывается после закрытия последнего окна документа. Это делается для того, чтобы сохранить память и "очистить". Чтобы отключить это поведение, выполните следующее:

defaults write -g NSDisableAutomaticTermination -bool TRUE

Конечно, чтобы отменить это, измените TRUE на FALSE .


Использование функций вместо скриптов

Наконец, я бы предложил поместить ваши скрипты в функцию, которая всегда доступна в вашей оболочке. Для этого добавьте сценарии в ваш ~/.bash_profile . Создайте этот файл, если он не существует.

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
}

Как только вы сохраните свой профиль bash и перезапустите оболочку, вы можете вызвать cw Preview foo.pdf отовсюду.

0

Ответ от slhck выглядит хорошо и тщательно. Осторожно, выполняя третью строку кода:

sudo codesign -f -s - /Applications/Preview.app

«Кажется» вызывало аварийное завершение Preview при каждом запуске:

Application Specific Information:
XPC domain creation failed: The code signature is not valid: The operation couldn’t be completed. (OSStatus error -67061.)

Согласно руководству по кодовому обозначению, что -f заставляет «кодовый знак заменить и существующую подпись», а -s - «подписывать код по указанному пути»… в данном случае -

По всей видимости, Preview теперь неправильно подписан и непригоден для использования. :(

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .