Как я могу запустить приложение с аргументами командной строки в Mac OS

60

Есть ли простой способ добавить аргументы командной строки в приложение на Mac? Например, чтобы запустить Opera в режиме киоска или использовать другой профиль в Firefox, я могу набрать

$ /Applications/Opera.app/Contents/MacOS/Opera -kioskmode
$ /Applications/Firefox.app/Contents/MacOS/firefox -P profilename -no-remote

В Windows я могу добавить аргументы к свойствам ярлыков, но поскольку Mac не использует ярлыки как таковые и не запускает приложения напрямую, это невозможно.

Я обнаружил, что запуск приложений через bash или Applescript частично работает:

# Bash
#!/bin/sh
/Applications/Firefox.app/Contents/MacOS/firefox -P default -no-remote

# Applescript    
do shell script "exec /Applications/Opera.app/Contents/MacOS/Opera -kioskmode"

Я могу сделать их исполняемыми и назначить значок, и все прекрасно работает, за исключением того, что при запуске любой из этих псевдопрограмм окно терминала или значок Applescript остаются открытыми до тех пор, пока приложение открыто. Предположительно, использование команды Applescript openпозволит избежать этого, но, поскольку я не запускаю приложение, поскольку оно упаковано (просто /Applications/Firefox), оно не работает.

Итак, есть ли лучший способ для запуска приложений с аргументами командной строки? Если нет, есть ли способ предотвратить постоянный сеанс терминала или значок Applescript, чтобы оставаться открытым, пока приложение открыто?

редактировать

Согласно странице вики Mozilla , лучше всего использовать скрипт для запуска приложения с аргументами. Добавление &в конец скрипта убивает постоянное окно терминала. Единственное раздражение сейчас заключается в том, что он открывает мертвое окно терминала, вышедшее из системы (что лучше, чем постоянное, но все же ...)

#!/bin/sh
/Applications/Firefox.app/Contents/MacOS/firefox -P default -no-remote &
Андрей
источник
2
Я все еще надеюсь на лучшие ответы на этот вопрос ...
Cregox
Когда вы запускаете задание, &которое по-прежнему принадлежит Терминалу, вы можете исправить это, добавив строку disown %/Applications/Firefox.app/Contents/MacOS/firefox после запуска, затем вы можете безопасно закрыть Терминал, используя AppleScript.
ocodo
ищите ответ Даниэля - он самый полный и совершенный на сегодняшний день (OSX 10.6.2 +).
Cregox

Ответы:

17

Вот мое лучшее решение: создайте Applescript с помощью:

do shell script "/Applications/Firefox.app/Contents/MacOS/firefox -P default -no-remote & killall Firefox.app"

И сохраните его как приложение .

Вы можете поместить любое приложение с любыми аргументами в первой части. Часть после &должна убить все, что вы назвали ваш скрипт + .app. Вы увидите, что приложение-скрипт вспыхивает в доке, но затем исчезает.

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

MJeffryes
источник
Это почти работает. Он по-прежнему ожидает выполнения экземпляра Firefox, пока не запустит killall, поэтому он вызывает отладчик, когда я закрываю Firefox, и приложение-скрипт все равно не исчезает. Хммм ...
Эндрю
Это странно. Вы сохраняете его как приложение, а затем дважды щелкаете по нему? Он не будет работать при запуске из редактора скриптов.
MJeffryes
Кроме того, я заметил, что поставил новую строку перед &. Удалите
символ
нет необходимости в & killall здесь, в Snow Leopard 10.6.x - но также не удалось найти способ заставить приложение убить себя самостоятельно, как только будет выполнено.
Cregox
1
@Pacerier Проверьте даты в этом ответе.
MJeffryes
28

Начиная с OS X 10.6.2, команда open может передавать аргументы приложению, которое она открывает, с помощью флага --args. Используемый AppleScript выглядит следующим образом:

do shell script "open -a /Applications/Firefox.app --args -P default -no-remote"

Это должно дать вам все поведение, которое вы хотите.

боб
источник
"Человек открыт", и вот оно! работал как шарм. --args флаг, а затем ваши аргументы.
Майкл Диммитт
1
Я пытался --argsс Chrome, и он не работает. Это будет работать только для первого экземпляра . Если вы попытаетесь запустить два --user-data-dirодновременно, вы не сможете сделать это с openпомощью старого /applications...метода. Кто-нибудь знает, почему ебать --args не работает?
Pacerier
1
@Pacerier, "open -n"
Саймон Райт
Чтобы добавить к этому, вы можете создать сценарий в редакторе сценариев, а затем сохранить как приложение.
Кевин С.
11

Откройте Automator и создайте приложение с помощью одного действия Run Shell Script :

 /Applications/Firefox.app/Contents/MacOS/firefox-bin -here-some-args &

Это приложение запустит Firefox и сразу же закроется, оставив только работающий Firefox.


Или создайте приложение с помощью AppleScript Editor со следующим кодом AppleScript:

do shell script "open -a '/Users/danielbeck/Applications/Firefox.app' --args -ProfileManager"

Оба работают нормально и не поддерживают приложение Terminal или скрипт более чем на секунду или около того. Используя Automator, вы можете даже создать Службу, если захотите.

Даниэль Бек
источник
1
Просто имейте в виду, что это open --argsбыло реализовано в 10.6.2, как уже упоминал Боб.
Cregox
Используя его для: open eclipse.app -nоткрыть второе рабочее пространство Eclipse. Очень удобно. Спасибо!
jonalv
Не удалось заставить его работать в Automator с действием «Run Shell Script» в MacOS 10.14. Однако в конечном итоге у меня был успех с AppleScript.
Кевин С.
8

Это старая дискуссия, но она все еще подходит для поиска в Google, поэтому я решил добавить пару ¢.

Вероятно, лучше использовать «идентификатор пакета», а не абсолютный путь к исполняемому файлу:

open -b com.google.Chrome --args --profile-directory="Profile 1"

Или в сценарии Apple:

do shell script "open -b com.google.Chrome --args --profile-directory='Profile 1'"

Что я еще не понял, так это как открыть новый экземпляр / окно с другим профилем, как только первый уже открыт. (Если я запустил AppleScript выше, затем еще один с «Профилем 2», тогда Chrome все равно просто откроет другое окно как «Профиль 1»). :(

user1722483
источник
-B функционально равен -a? Насколько они разные?
Pacerier
7

В этом сценарии нет необходимости (как предлагали некоторые другие ответы) использовать killall (или аналогичный) для уничтожения родительского процесса приложения AppleScript («апплет»). Это может даже иметь неблагоприятные побочные эффекты, если имя / шаблон, заданный для killall, совпадает с чем-то большим, чем просто процесс родительского апплета (например, другой, одновременно запускающий приложения AppleScript (если в качестве шаблона используется «апплет»)).

Нечто подобное kill $PPIDможет быть более разумным, но мы можем не предполагать, что апплет приложения AppleScript всегда является непосредственным родителем оболочки, запускаемой скриптом do shell . К счастью, есть совершенно разумный способ сделать то, что вам нужно.

В соответствии с TN2065 (в разделе «Я хочу запустить фоновый серверный процесс; как сделать так, чтобы сценарий оболочки не ожидал завершения выполнения команды?»), Правильный метод - перенаправить stdout и stderr и заставить оболочку запускать программу в фоновом режиме. ,

Используйте Script Editor, чтобы сохранить следующую программу как приложение AppleScript:

do shell script ¬
    "/Applications/Firefox.app/Contents/MacOS/firefox-bin \\
        -P default -no-remote \\
        >/dev/null 2>&1 &"

(добавлены функциональные разрывы строк, чтобы сделать его «узким»; удалите ¬и \\и поместите все в одну длинную строку, если хотите)

Он будет работать достаточно долго для запуска Firefox и будет корректно завершать работу, пока Firefox продолжает работать.

Перенаправление является обязательным, поскольку сценарий оболочки не только ожидает выхода своего непосредственного дочернего элемента (оболочки), но также ожидает (все экземпляры) доступных для записи концов каналов, которые он создает для закрытия оболочки stdout и stderr. , Stdout и stderr оболочки ( делают каналы сценария оболочки ) наследуются программами, которые запускаются без перенаправления (даже те, которые выполняются в фоновом режиме &); перенаправление гарантирует, что оболочка является последней, которая содержит доступные для записи концы каналов. Таким образом, сценарий do shell будет возвращен сразу после выхода из оболочки, что позволит завершить работу самого приложения AppleScript (поскольку сценарий do shell является последним выражением в программе AppleScript).

Другие ответы, которые используют open inside, выполняют работу сценария оболочки, потому что open (фактически LaunchServices) выполняет эквивалентную работу по фонованию результирующей программы и отправке ее stdout и stderr в другое место.

Крис Джонсен
источник
это очень интересно Интересно, работает ли это до 10.6.2 ... но я все еще думаю, что использование open --argsвыглядит чище. Есть ли какой-либо недостаток при использовании любого из них?
Cregox
1
Я знаю, что этот метод работает в 10.4. У меня сложилось впечатление, что сценарий do shell всегда работал следующим образом (он был добавлен в стандартные дополнения OSAX в AppleScript 1.7 , поставляемом с Mac OS X 10.1). Если вы готовы принять 10,6, то open --args, вероятно, все в порядке.
Крис Джонсен
@ChrisJohnsen, ссылка вниз ........
Pacerier
4

AppleScript

do shell script "/Applications/Google\\ Chrome.app/Contents/MacOS/Google\\ Chrome --incognito & killall applet"

Две точки там.

  1. Пространство освобождается обратной косой чертой, которая снова удаляется обратной косой чертой
  2. Апплет killall может вызвать проблемы, потому что могут работать другие апплеты
  3. Сохранить как программу

Однако это хорошо работает на 10.6.5

анонимный
источник
appletотносится к?
Pacerier
3

Следующее должно позволить вам указать аргументы командной строки для самого .app:

Щелкните правой кнопкой мыши по пакету .app, выберите «Показать содержимое пакета», перейдите к Info.plist, дважды щелкните его, найдите ключ Args, отредактируйте.

В данный момент у меня нет под рукой машины с OS X, поэтому я не могу проверить, можете ли вы также сделать это с псевдонимом (если вы хотите оставить исходный .app без аргументов и т. Д.).

Dav
источник
К сожалению, в списке нет ключа args. Согласно Mozilla, вы должны использовать скрипт - wiki.mozilla.org/MailNews:Logging#Mac
Эндрю
Также обратите внимание, что изменение содержимого пакета (например, Info.plist) может вызвать проблемы с подписью кода: bridge.grumpy-troll.org/2011/01/…
drevicko
2

Оберните ваше приложение в программе запуска AppleScript.

Вот шаги.

  1. Создайте AppleScript со следующим содержимым и сохраните его как приложение (в данном примере он называется «Firefox 3 launcher.app»).

    set pathToApp to (POSIX path of (path to me)) & "Firefox 3.app"
    do shell script "open -a \"" & pathToApp & "\" --args -P default -no-remote"
    
  2. Зайдите в это приложение в Finder, щелкните по нему правой кнопкой мыши, покажите содержимое пакета.

  3. Поместите ваше приложение в корень содержимого пакета. (В этом примере это будет «Firefox 3.app»)

    Результат: / Приложения / Firefox 3 launcher.app/Firefox 3.app

  4. Теперь вы можете открыть панель запуска приложений.

Примечания:

  • Автоматические обновления упакованного приложения должны работать в большинстве случаев.
  • Должна быть возможность сделать любое перетаскивание на панель запуска, автоматически перенаправленную в упакованное приложение (с немного большим количеством сценариев).
  • Панель запуска автоматически завершает работу после запуска упакованного приложения.
  • Преимущество этого метода состоит в том, что существует небольшой риск прямого открытия упакованного приложения.
jlgrall
источник
1

Почему вы не используете:

#!/bin/sh
open /Applications/Firefox.app

Просто, но это работает.


источник
2
Терминал откроется, если вы это сделаете.
MJeffryes
0

У openкоманды есть необязательный --argsаргумент, значение которого будет передано открытому приложению в качестве аргументов. Например:

open /Applications/TextEdit.app --args example.txt
ecnepsnai
источник