Запустить сценарий оболочки в OS X без появления окна терминала?


23

Я пытаюсь настроить несколько сочетаний клавиш, которые открывают определенные сеансы iTerm, что я смог сделать с помощью BetterTouchTool и немного магии AppleScript. Проблема в том, что OS X настаивает на том, чтобы открыть окно терминала для любого сценария оболочки, который вы выполняете через графический интерфейс (например, из Finder или как сочетание клавиш из BetterTouchTool). Окно терминала не появляется, если я запускаю скрипт напрямую с другого терминала.

Обходной путь, который я нашел, заключался в том, чтобы обернуть сценарий в каталог .app, что решает проблему лишнего окна терминала, но имеет некоторые другие проблемы (например, OS X, кажется, обрабатывает каждое получающееся окно iTerm как отдельное приложение, загромождая мою док-станцию ). (РЕДАКТИРОВАТЬ: это поведение на самом деле было вызвано ошибкой в ​​моем скрипте, см. Ниже)

Я также попытался назначить приложение «Терминал» другому виртуальному рабочему столу в настройках «Пространства», чтобы убрать его из поля зрения, но затем оно сначала переключится на этот рабочий стол, прежде чем запускать сценарий.

Есть ли способ полностью отключить это поведение? Я уже нашел параметр в настройках терминала, чтобы закрыть окно после завершения сценария, но все еще раздражает, что окно терминала всплывает на секунду.


Извините, я не совсем понимаю. Что вы хотите сделать с этими сценариями оболочки? Хотите открыть iTerm через скрипт оболочки? Вы говорите исключительно о Terminal.app или смешиваете iTerm с «Terminal» в своем вопросе? Не могли бы вы опубликовать пример того, что вы пытаетесь запустить?
Slhck

Я настроил несколько сеансов iTerm для запуска обычной оболочки, открытия консоли Rails, отображения журнала Rails и т. Д. Я использую исключительно iTerm, и терминал открывается автоматически OS X по любой глупой причине. Но, во всяком случае, я нашел решение, чтобы заставить подход с использованием пакетов работать правильно (см. Отредактированный вопрос).
Тупейра

Я вижу! Что ж, было бы здорово, если бы вы могли ответить на свой вопрос (используя кнопку ниже) и рассказать нам, что вы сделали, или как вы решили проблему. Возможно, опубликуйте несколько примеров в своем вопросе, а затем просто добавьте краткий ответ. Таким образом, если кто-то наткнется на ваш пост, он может чему-то научиться!
slhck

Ну, у меня до сих пор нет ответа на конкретный вопрос (то есть, как полностью избежать Терминала, не используя оболочку .app), поэтому я бы предпочел оставить его открытым, если кто-нибудь сможет меня просветить.
Тупейра

1
Я все еще в замешательстве. Вы не хотите запускать их через .app, созданный Automator?
Slhck

Ответы:


21

Откройте Automator , выберите « Приложение» , добавьте действие « Выполнить сценарий оболочки» и введите команду «Shell» между кавычками (если у вас есть файл, вы можете просто перетащить его).

Помимо воспроизведения, теперь вы можете сохранить его (как приложение в любом месте) и даже установить значок .


Я пытался запустить команду таким образом из полноэкранного приложения, но оно всегда открывалось в фоновом режиме. Мне пришлось добавить фоновую команду в оболочке неблокирующим способом, добавив a, &а затем вызвать AppleScript, чтобы вывести приложение (в моем случае mplayer) на передний mplayer myvideo.avi &; osascript -e 'tell application "System Events" to set frontmost of the first process whose displayed name is "mplayer" to true'
план

Крутой взлом @mcb. Но я не понимаю почему. Обычно мы хотим скрыть окно терминала, потому что оно откроет другое окно, которое является основным. Если вам нужно первое окно терминала mplayer, я полагаю, оно не открывает еще одно окно, и так зачем вам его вообще скрывать?
cregox

Я использую mplayerдля воспроизведения видео из слайд-шоу (в Skim). Существует ошибка, из-за которой проигрыватель остается в фоновом режиме, если Skim установлен в полноэкранный режим, хотя я не уверен, относится ли этот дефект только к Skim или ко всем полноэкранным приложениям, поэтому я решил опубликовать свое решение здесь.
Ленар Хойт

6

Вот быстрый и грязный пример, почти без усилий (для приложения с именем "myapp"):

  1. Составьте частичную иерархию приложений:

        mkdir -p ./myapp.app/Contents/MacOS
    
  2. Убедитесь, что в первой строке вашего скрипта указан полный путь к нужной программе, например,

    #!/bin/bash
    
  3. Назовите свой сценарий оболочки «myapp» (без кавычек, без расширения), дайте ему разрешение на выполнение, а затем поместите его в подкаталог MacOS. Чтобы дать ему разрешение на выполнение:

    chmod ugo+x myapp
    
  4. Перейдите в подкаталог Contents и создайте файл PkgInfo, содержащий строку: APPL ???? [без конца строки в конце строки!] Используйте утилиту cat (1) для создания файла:

    cat > PkgInfo
    APPL????
    

    После того, как вы ввели строку (не нажимайте return!), Введите два управляющих D, которые закроют
    файл без разделителя строк и вернут вас к приглашению оболочки.)

  5. Дважды щелкните ваше новое «приложение» из поиска. Он будет работать без окна.


Не работало на 10.13.6, сообщение об ошибке гласит: «Невозможно открыть приложение« LoginSessionTimeLimit.app », потому что оно не поддерживается на этом типе Mac».
Дуглас провел

1
Работал в Мохаве (10.14.3) для меня. Мне очень понравился этот подход. Благодарю.
loco.loop

Работал у меня на 10.13.6. @Douglas Попробовал запустить скрипт «вручную», то есть из Терминала. Вероятно, он выходит с ошибкой, следовательно, он не работает для вас ...
marekful

Большой! Тестирование работы в Мохаве 10.14.6
Никола Минготти

4

Возможно, вы захотите проверить Platypus , который создает приложения Mac OS X из сценариев оболочки и других интерпретируемых сценариев.


3

Вот небольшой обходной путь, на случай, если вы захотите запускать такие приложения, как Альфред . Я использую его каждый день, и я купил Powerpack , который позволяет запускать сценарии без вывода сообщений .

введите описание изображения здесь

Они не будут открывать терминал при запуске и могут быть связаны с любой последовательностью ключевых слов. Они могут даже включать параметры и иметь дополнительные параметры:

введите описание изображения здесь

Я использую это для некоторых маленьких фрагментов, и это очень гибко.



1

Если вы добавите ключ LSUIElementи установите его 1в Info.plistсвоем приложении, он не создаст значок в Dock.

Вот Info.plistмое небольшое приложение-скрипт:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleExecutable</key>
    <string>launch</string>
    <key>CFBundleIconFile</key>
    <string>launch</string>
    <key>LSUIElement</key>
    <string>1</string>
</dict>
</plist>

Спасибо, но это, похоже, не дает эффекта. Я также попытался touchиспользовать пакет, чтобы убедиться, что использовалась новейшая версия. Но в любом случае мне не очень нравится групповой подход, потому что кажется, что он всегда будет создавать отдельные экземпляры приложения
toupeira

Мне не помогло и прикосновение (я пытался отключить LSUIElement), есть какой-то другой вид кэширования, но помогло сжатие и извлечение приложения. Почему вам не нравится пакетный подход? Также вы можете использовать яблочный скрипт и просто запустить do shell script "say 'arsti'", это не откроет окно терминала.
Тиг

Хорошо, оказывается, я просто идиот ;-) Я не смог найти надежный способ проверить, запущено ли уже приложение с AppleScript, поэтому я использовал обычный скрипт bash, который вызывает pgrep, а затем передает соответствующий код непосредственно osascript(интерпретатор AppleScript). Проблема в том, что pgrepпришла от Homebrew, а не по умолчанию $PATH. Поэтому мой скрипт всегда запускал новый экземпляр iTerm, даже если он уже работал. После добавления полного пути к pgrepсценарию пакетный подход, в конце концов, работает нормально, так что я думаю, что сейчас я счастлив ;-)
toupeira

Комбинируя этот ответ с ответом из @JeffB выше, и с упрощенной версией Info.plist @tig (я удалил клавиши CFBundleExecutableи и CFBundleIconFile), я получил это, чтобы работать отлично.
Дейв Лэнд

0

Вот немного обходного пути:

Скомпилируйте appleScript, который вызывает скрипт оболочки :)

osacompile -e 'do shell script "cd ~; echo aaa > temp.txt"' -o ~/name_of_script.scpt

osacompileБудет компилировать 'do shell script "XXX"'AppleScript фрагмент кода. Ваш сценарий оболочки XXX.

Остерегайтесь цитирования, сценарий оболочки должен быть заключен в кавычки, чтобы обойти оболочку, которую вы используете для ее компиляции, без изменений.

Но это может быть запущено из BetterTouchTool без каких-либо причуд.


0

Есть другая возможная тренировка. Сохраните ваш сценарий оболочки в рабочем процессе автоматизатора. Запустите рабочий процесс с помощью launchd. Код:

/usr/bin/automator /path/to/the/file.workflow

Это не запустит ни одну программу и не будет отображаться в строке меню и будет более тихим, чем приложение Platypus.

Еще лучший способ выполнения сценариев оболочки - это прямой запуск.

/bin/bash /path/to/shellScript.command

выполнит команду ультра тихо в фоновом режиме.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.