Вопрос: Как полностью отключить процесс от терминала?


Я использую Tilda (выпадающий терминал) на Ubuntu в качестве моей «центральной команды» - в значительной степени, как другие могут использовать GNOME Do, Quicksilver или Launchy.

Тем не менее, я борюсь с тем, как полностью отключить процесс (например, Firefox) от терминала, с которого он был запущен, т. Е. Предотвратить такой (не) дочерний процесс

  • прекращается при закрытии исходного терминала
  • «загрязняет» исходный терминал через STDOUT / STDERR

Например, чтобы запустить Vim в «правильном» терминальном окне, я попробовал простой скрипт, например:

exec gnome-terminal -e "vim $@" &> /dev/null &

Тем не менее, это все еще вызывает загрязнение (также, как правило, передача имени файла не работает).


274
2018-03-23 11:59


Источник


Это тоже хороший вопрос. Я считаю, что справедливо считать Bash языком программирования, хотя в действительности этот вопрос, вероятно, больше связан с системой sysadmin ...
Это дубликат этого вопроса stackoverflow.com/questions/285015/... - Dana the Sane
dup of:superuser.com/questions/177218/... - behrooz
Ваш прецедент не описывает полную отстраненность, как таковой. - jiggunjer


Ответы:


Прежде всего; после того, как вы запустили процесс, вы можете выполнить его сначала, остановив его (нажмите Ctrl-Z), а затем набрав bg чтобы он возобновился в фоновом режиме. Теперь это «работа», и ее stdout/stderr/stdin все еще подключены к вашему терминалу.

Вы можете запустить процесс, как это было указано сразу, добавив «&» в конец:

firefox &

Чтобы запустить его в фоновом режиме, отключите его, используйте следующее:

firefox </dev/null &>/dev/null &

Дополнительная информация:

nohup это программа, которую вы можете использовать для запуска приложения так что его stdout / stderr может быть отправлен в файл вместо этого, и что закрытие родительского скрипта не будет SIGHUP дочерним. Тем не менее, вы должны были предусмотрительно использовать его до начала работы приложения. Из-за пути nohup работает, вы не можете просто применить его к запущенному процессу,

disown это bash builtin, который удаляет задание оболочки из списка заданий оболочки. Это в основном означает, что вы не можете использовать fg, bg на нем больше, но что более важно, когда вы закрываете оболочку, она не будет висеть или отправлять SIGHUP к этому ребенку. В отличие от nohup, disown используется после процесс был запущен и подчёркнурован.

Что ты не может do, это изменение stdout / stderr / stdin процесса после его запуска. По крайней мере, не из оболочки. Если вы запустите свой процесс и сообщите ему, что его stdout является вашим терминалом (это то, что вы делаете по умолчанию), тогда этот процесс настроен для вывода на ваш терминал. Ваша оболочка не имеет отношения к настройкам FD процессов, это просто то, что сам процесс управляет. Сам процесс может решить, закрыть ли его stdout / stderr / stdin или нет, но вы не можете использовать свою оболочку, чтобы заставить ее это сделать.

Чтобы управлять выходом фонового процесса, у вас есть множество опций из сценариев, «nohup», вероятно, первый, кто приходит на ум. Но для интерактивных процессов вы начинаете, но забываете тишину (firefox < /dev/null &>/dev/null &) На самом деле вы не можете много сделать.

Я рекомендую вам получить GNU screen, С помощью экрана вы можете просто закрыть свою рабочую оболочку, когда выход процесса станет затруднительным и откроет новый (^Ac).


О, и, кстати, не используйте "$@«где вы его используете.

$@означает, $1, $2, $3 ..., который превратит вашу команду в:

gnome-terminal -e "vim $1" "$2" "$3" ...

Вероятно, это не то, что вы хотите, потому что один аргумент. использование $1 чтобы показать, что ваш скрипт может обрабатывать только один аргумент.

Очень сложно заставить несколько аргументов правильно работать в сценарии, который вы дали (с помощью gnome-terminal -e) потому как -e принимает только один аргумент, который является командной строкой оболочки. Вам придется закодировать свои аргументы в одном. Самый лучший и самый надежный, но довольно неуклюжий способ:

gnome-terminal -e "vim $(printf "%q " "$@")"

308
2018-03-23 13:18



Большое спасибо за это! К сожалению, я могу только принять один ответ. Я закончил с "nohup $ @ &> / dev / null &" и "alias wvim = 'launch.sh gnome-terminal -x vim'"
Какой фантастически подробный и информативный ответ. +1 - Teekin
@ Привет-Ангел, когда вы закрываете интерактивную оболочку bash, bash HUPs все активные задания. Когда вы делаете ^ Z и bg процессом, это все еще работа, будь то фоновая. Чтобы удалить его как задание, используйте disown, то процесс будет продолжать жить после закрытия оболочки, так как bash больше не будет HUP. - lhunath
Не будет использовать $* вместо $@ исправить проблему отдельных строк уже? - sjas
То, что вы не можете сделать, это изменение stdout / stderr / stdin процесса после его запуска. - Не совсем верно. использование reptyr для этого. - Stefan Seidel


nohup cmd &

nohup полностью отделяет процесс (демонзирует его)


190
2018-03-23 12:17



Хотя краткий является ценным, полнота более ценна. Хотя nohup является GNU coreutil, здесь будет уместен ответ только на bash (или примечание о том, что он не один). Хороший ответ тем не менее. - Limited Atonement
nohup просто игнорирует SIGHUP сигнал. Он выполняет этот процесс в обычном режиме. Нет демонизации. - nemo
@nemo. Это означает, что процесс не отделяется, а будет отсоединен (и ребенок init), если оболочка вышла ... правильно? - Noldorin
@Noldorin Да. Игнорирование SIGHUP, которое отправляется при завершении оболочки, оставит дочерний процесс запущенным и переместится в init. - nemo
@nemo nohup также замалчивает стандартные входы / выходы. Последующие действия полностью прекращаются. - jiggunjer


Если вы используете bash, пытаться disown [jobspec]; видеть Баш (1),

Другой подход, который вы можете попробовать: at now, Если вы не являетесь суперпользователем, ваше разрешение на использование at могут быть ограничены.


51
2018-03-23 12:05



«disown», похоже, не является внутренней командой bash (недоступной на моей машине, и я использую bash). «nohup», как предположил Бен, может быть намного лучшим (и стандартным) способом сделать это.
никогда не думал об использовании «в», спасибо за идею! - cadrian
at делегировать исполнение кому-то другому, мне это нравится! +1 - Ninsuo
Как точка отсчета, это работает в zsh также. - Coderer
Также, disown кажется, не имеет желаемого эффекта с gnome-terminal-disownПосле завершения работы терминала все процессы уничтожаются. Мне бы хотелось узнать, почему и как. - Kyle Strand


Читая эти ответы, я был под первым впечатлением, что выдача nohup <command> & было бы достаточно. Запустив zsh в gnome-terminal, я обнаружил, что nohup <command> & не мешало моей оболочке убивать дочерние процессы при выходе. Несмотря на то что nohup полезно, особенно с неинтерактивными оболочками, он только гарантирует это поведение, если дочерний процесс не сбрасывает свой обработчик для SIGHUP сигнал.

В моем случае, nohup должны были помешать сигналу зависания от приложения, но дочернее приложение (в данном случае, проигрыватель VMWare) сбрасывает SIGHUP обработчик. В результате, когда терминал-эмулятор выходит, он все равно может убить ваши подпроцессы. Насколько мне известно, это может быть разрешено только благодаря тому, что процесс удаляется из таблицы заданий оболочки. Если nohup переопределяется встроенной оболочкой, как это иногда бывает, этого может быть достаточно, однако, если это не так ...


disown это оболочка, встроенная в bash, zsh, а также ksh93,

<command> &
disown

или

<command> &; disown

если вы предпочитаете однострочные. Это имеет как правило желательный эффект удаления подпроцесса из таблицы рабочих мест. Это позволяет вам выйти из эмулятора терминала, не случайно сигнализируя о дочернем процессе. Независимо от того, что SIGHUP обработчик выглядит, это не должно убивать ваш дочерний процесс.

После отказа, процесс по-прежнему является дочерним элементом вашего эмулятора терминала (играйте с pstree если вы хотите посмотреть это в действии), но после выхода из эмулятора терминала вы увидите, что он подключен к процессу init. Другими словами, все так, как должно быть, и, как вы, вероятно, хотите, чтобы это было.

Что делать, если ваша оболочка не поддерживает disown? Я решительно выступаю за переход на тот, который делает, но в отсутствие этого варианта у вас есть несколько вариантов.

  1. screen а также tmux могут решить эту проблему, но они намного более тяжелые весовые решения, и мне не нравится запускать их для такой простой задачи. Они гораздо более подходят для ситуаций, в которых вы хотите поддерживать tty, как правило, на удаленной машине.
  2. Для многих пользователей может быть желательно увидеть, поддерживает ли ваша оболочка возможность, например, zsh setopt nohup, Это можно использовать, чтобы указать, что SIGHUPне следует отправлять на задания в таблице рабочих мест, когда оболочка завершается. Вы можете применить это непосредственно перед выходом из оболочки или добавить ее в конфигурацию оболочки, например ~/.zshrc если вы всегда этого хотите.
  3. Найдите способ редактирования таблицы заданий. Я не мог найти способ сделать это в tcsh или csh, что несколько тревожно.
  4. Напишите небольшую программу C для разветвления и exec(), Это очень плохое решение, но источник должен состоять только из пары десятков строк. Затем вы можете передавать команды в качестве аргументов командной строки программе C и, таким образом, избегать записи, специфичной для процесса, в таблице заданий.

34
2018-01-22 17:08





  1. nohup $ COMMAND &

  2. $ COMMAND & disown

  3. команда setsid

Я использую номер 2 в течение очень долгого времени, но номер 3 работает так же хорошо. Кроме того, disown имеет флаг «nohup» для «-h», может отключить все процессы с помощью «-a» и может отключить все запущенные процессы с помощью «-ar».

Молчание выполняется с помощью $ COMMAND &> / dev / null.

Надеюсь это поможет!


23
2017-08-25 14:39





Я думаю, экран может решить вашу проблему


9
2018-03-25 01:51





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

Сравните это:

> jobs # shows nothing
> firefox &
> jobs
[1]  + Running                       firefox

К этому:

> jobs # shows nothing
> (firefox &)
> jobs # still shows nothing
>

Это удаляет firefox из списка рабочих мест, но он все еще привязан к терминалу; если вы вошли в этот узел через 'ssh', попытка выйти из системы все равно будет приостановлена.


8
2018-03-23 14:55





Отключить команду запуска оболочки tty через под-оболочку, например.

(Команда) &

Когда выход терминала закрыт, но процесс все еще жив.

проверить -

(sleep 100) & exit

Открыть другой терминал

ps aux | grep sleep

Процесс все еще жив.


6
2017-08-07 05:18



Это именно то, что мне нужно. Я пытаюсь добавить консольный ярлык для возвышенного текста, и он отлично работает, вот что я получил: («/ opt / Sublime Text 2 / sublime_text» $ @) & - Ron E


Самый простой и правильный ответ для bash:

command & disown

Вам не нужно отделять процесс от терминала, а от оболочки.


6
2018-05-05 11:55



Работайте отлично. Спасибо. - Royi


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


4
2018-03-23 12:03



Я мог бы поклясться, что пробовал nohup, прежде чем использовать exec, но, по-видимому, не так, потому что он работает следующим образом: nohup gnome-terminal -e "vim $ @" &> / dev / null &


Фоновое и предварительное задание - это, вероятно, одна из первых вещей, которые должен знать каждый системный администратор Unix.

Вот как это делается с bash:

./script.sh
# suspend process
{ctrl-Z}
# background process
bg
# list all backgrounded jobs
jobs
# bring it back to foreground
fg

4
2018-05-22 23:00