Как предотвратить нежелательное завершение работы приложения, запущенного в Терминале?

10

Я запускаю приложения из терминала с помощью таких команд:

/Applications/Mail.app/Contents/MacOS/Mail &

Важной частью является  &.

  • Для Unix / Linux / Solaris:

    • В школе я узнал, что добавление программы  &заставляет программу жить самостоятельно.
    • Я очень хорошо помню, как запускал команду вроде,  xeyes &и программа работала безопасно даже после закрытия оболочки.
  • В Mac OS X (внутри Unix):

    1. Я запускаю приложение  &и закрываю окно терминала: приложение закрывается!
    2. Почему это нежелательное поведение происходит в Mac OS X?
    3. Как это можно исправить?
Николас Барбулеско
источник
Связанный вопрос: apple.stackexchange.com/q/119319/20773
Eric3

Ответы:

7

«Стандартный» способ достижения того, чего вы хотите достичь (в OS X, а также в Linux, FreeBSD или других системах), заключается в использовании команды nohup:

nohup program &

Это запустится program, что будет работать в фоновом режиме относительно оболочки из-за &- и будет игнорировать сигналы зависания из-за команды nohup.

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

jksoegaard
источник
1
Это создает файл nohup.outв текущей папке. Даже когда нечего писать. Через несколько недель у меня будут файлы nohup.outвезде на моем Mac. :-(
Николас Барбулеско
1
@NicolasBarbulesco Используйте либо nohup command>/dev/null&или command&disown.
Lri
6

Когда вы закрываете окно терминала, оно отправляет SIGHUP (сигнал зависания) в оболочку, которая затем отправляет SIGHUP всем запущенным процессам . Это традиционное поведение для bash и многих других оболочек, и традиционным решением этого является использование nohup.

Существуют различия между различными машинами Unix, поэтому возможно, что используемые вами эмуляторы терминала или используемые вами оболочки работают по-разному. Но это не относится к OS X. Например, есть вопрос по этой же проблеме в Ubuntu.

Алан Шутко
источник
6

Используя амперсанд " &", вы говорите терминалу запустить процесс в фоновом режиме самой оболочки. Таким образом, когда вы закрываете оболочку (и убиваете процесс), графический интерфейс (сам Mail.app) также закрывается.

Правильная команда для запуска Mail из терминала:

open -a Mail; exit

Редактировать: Я только что нашел это на U & L Stack Exchange: Что означает амперсанд в конце строки сценария оболочки? Предоставленные ответы превосходны и объясняют, что именно происходит, более подробно и лучше, чем я когда-либо мог! Я настоятельно рекомендую прочитать это.

njboot
источник
Как насчет передачи параметров командной строки в приложение? Как это:/Users/nicolas/Desktop/Firefox-29-fr/Firefox.app/Contents/MacOS/firefox -profile "/Users/nicolas/Desktop/Firefox-29-fr/Profil-Firefox-29-fr/" -no-remote &
Николас Барбулеско
2
@NicolasBarbulesco Это отдельный вопрос - откройте справочную страницу man, и я думаю, что вопрос здесь
user151019
Как насчет запуска определенного приложения, не находящегося внутри /Applications, а по определенному пути? Как это:/Users/nicolas/Desktop/Firefox-29-fr/Firefox.app/Contents/MacOS/firefox -profile "/Users/nicolas/Desktop/Firefox-29-fr/Profil-Firefox-29-fr/" -no-remote &
Николас Барбулеско
@NicolasBarbulesco откройте [полный путь] или перейдите в каталог и откройте [файл]. Вы можете использовать ~ / для своей домашней папки и специальный символ «звездочка» в качестве более короткой записи, предполагая, что никакие другие строки не соответствуют значению, т.е. IE: ~ / De * / Fire * ... и так далее. Или просто напишите простой скрипт: cat> nameofscript ..... #! / bin / sh .... открыть [полный путь] .... ^ D ..... chmod + x nameofscript ...... \ nameofscript .... и необязательно, mv nameofscript $ PATH / yourpersonalbin. Рекомендую читать человеку открытым. Это простая команда, и, как простая команда, компромисс не так уж и силен.
njboot
1
Извините, все еще нужно использовать аргумент -a:open -a Applications/Mail.app/Contents/MacOS/Mail; exit
njboot
3

@jksoegaard имеет правильные команды, но, как вы упомянули в комментарии, он создает файл nohup.out. Чтобы остановить создание файла nohup.out, вам нужно перенаправить STDOUT и STDERR куда-нибудь еще. Полная команда будет nohup program &>/dev/null &. Это запустит вашу программу в фоновом режиме, игнорируя SIGHUP и отправляя все STDOUT и STDERR в / dev / null.

Однако, если вы не забыли добавить nohup (как в исходном вопросе), вы можете использовать disown -arhкоманду, чтобы отметить все фоновые запущенные задания, чтобы игнорировать SIGHUP.

Бессонница программного обеспечения
источник
Хороший ответ, но все еще сложный. И красивое изображение профиля. :-)
Николас Барбулеско
3

Я нашел решение:

(/Applications/Mail.app/Contents/MacOS/Mail &)

Это просто, это красиво, и это работает!

Скобки  ( )запускают команду в под-оболочке.

Николас Барбулеско
источник
- & возвращает из программы в оболочку без ожидания, так что вы можете продолжать использовать оболочку или прекратить ее, не выходя из программы.
r_alex_hall
0

Или вы можете попробовать open -a /Applications/Mail.app

Использование: open [-e] [-t] [-f] [-W] [-R] [-n] [-g] [-h] [-s] [- b] [-a] [имена файлов] [--args arguments]
Справка: Открыть открывает файлы из оболочки.
      По умолчанию открывает каждый файл, используя приложение по умолчанию для этого файла.
      Если файл имеет форму URL, файл будет открыт как URL.
Параметры:
      -a Открывается с указанным приложением.
      -b Открывается с указанным идентификатором пакета приложения.
      -e открывается с помощью TextEdit.
      -t Открывается в текстовом редакторе по умолчанию.
      -f Читает ввод из стандартного ввода и открывается с TextEdit.
      -F --fresh Запускает приложение заново, то есть без восстановления окон. Сохраненное постоянное состояние теряется, за исключением документов без названия.
      -R, --reveal Выбирает в Finder вместо открытия.
      -W, --wait-apps Блокирует закрытые используемые приложения (даже если они уже запущены).
          --args Все остальные аргументы передаются в argv в функцию main () приложения, а не открываются.
      -n, --new Открыть новый экземпляр приложения, даже если он уже запущен.
      -j, --hide Запускает скрытое приложение.
      -g, --background Не выводит приложение на передний план.
      -h, --header Выполняет поиск местоположения файла заголовка для заголовков, соответствующих заданным именам файлов, и открывает их.
      -s Для -h, SDK для использования; если указан, то ищутся только те SDK, имена которых содержат значение аргумента.
                        В противном случае используется SDK с самой высокой версией в каждой платформе.
Halomaple
источник
-2

Я нашел решение: бороться со злом со злом.

Я запускаю свое приложение с такой командой:

/Applications/Mail.app/Contents/MacOS/Mail & exit

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

Но это решение не очень удобно.

Николас Барбулеско
источник
1
Вы действительно должны открывать приложения, которые связаны с открытым . Это будущее, как изменение содержимого пакета, так и каноническое.
Ян С.
@Ian - Здесь я особенно заинтересован в открытии приложений, которые находятся по определенному пути, а не в /Applicationsи не связаны с моим Mac.
Николас Barbulesco
1
.appпапки называются «связками», и openкоманда может запускать их, находятся ли они в /Applicationsпапке или в любой другой папке. Термин «комплект» в данном контексте не означает «поставляется с OS X».
никто не
Открыть - это то же самое, что щелкнуть значок. Это не то же самое, что запуск приложения из командной строки.
Тед Бигхам