Linux как отвязать процесс от терминала

Обновлено: 05.07.2024

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Иногда нужно «отвязать» программа от окна терминала, в котором она запущена. Например, вы подключились к удалённому серверу по SSH, запустили задачу, которая не является демоном, но выполнение которой требует большого времени (может быть дни и месяцы). Если вы закроете терминал или просто оборвёте SSH сессию, то запущенная программа попросту прекратит свою работу.

Ещё один пример ситуации, когда это может понадобиться, вы работаете с безголовым сервером (без графического окружения рабочего стола) и по этой причине не можете открыть несколько терминальных окон. Поэтому вы хотите перевести программу в фон, чтобы продолжить работу с терминалом.

В этой статье описаны варианты, как закрыть терминал без остановки запущенной в нём программы.

Для этого есть два решения:

Давайте разберёмся, а в чём различия между

Давайте для начала взглянем, что происходит, когда команда запускается из интерактивной оболочки (подключённой к терминалу) без & (и без какого либо перенаправления). Поэтому давайте предположим, что вы напечатали просто foo (в качестве примера команды), тогда:

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

Теперь давайте посмотрим, что происходит, когда мы переводим процесс в фон, это делается набором foo &:

  • Создаётся запущенный процесс foo.
  • Процесс наследует stdout/stderr из оболочки (поэтому он всё ещё пишет в терминал).
  • Процесс, в принципе, также наследует stdin, но как только он пытается читать из stdin, он приостанавливается.
  • Он помещается в список фоновых задач, которыми управляет оболочка, что в частности означает:

  • Он выводиться по jobs и к нему можно получить доступ используя %n (где n – это номер задачи).
  • Его можно перевести на задачу переднего плана, используя fg, в этом случае он продолжится, будто бы вы не использовали с ним & (и если раньше он останавливался, при попытке читать стандартный ввод, теперь он может работать с чтением стандартного ввода из терминала).
  • Если оболочка получает SIGHUP, она также отправляет SIGHUP процессу. В зависимости от оболочки и возможных включённых опций оболочки при завершении оболочки она также будет отправлять процессу SIGHUP.

Теперь disown удаляет задачу из списка задач оболочки, следовательно все приведённые выше подпункты больше не применяются (включая отправку оболочкой процессу сигнала SIGHUPl). Тем не менее, помните, что он всё ещё подключён к терминалу, поэтому если терминал разрушен (что может случиться если это был pty, как те, которые создаются xtermor или ssh, и контролирующая программа завершена закрытием xterm или закрытием SSH-подключения), программа потерпит неудачу, как только она попытается прочитать из стандартного ввода или записать в стандартный вывод.

Что делает nohup, с одной стороны, она активно отделяет процесс от терминала:

Помните, что nohup не удаляет процесс из контроля задач оболочки и также не переводит его в фон (но поскольку задача nohup на переднем плане практически бесполезно, то обычно она запускается с использованием &). Например, в отличие от disown, оболочка всё ещё будет говорит вам, когда задача nohup завершена (конечно, если оболочка не закрылась раньше этого).

  • & переводит задачу в фон, это приводит к блокировке попыток читать стандартный ввод и делает так, что оболочка не ждёт завершения задачи.
  • disown удаляет процесс из контроля задач оболочки, но всё ещё оставляет её связанной с терминалом. Одним из результатов этого является то, что оболочка не отправит SIGHUP. Очевидно, что это может быть применимо только к фоновым задачам, поскольку вы не можете ввести это когда запущена работа на переднем плане.
  • nohup отсоединяет процесс от терминала, перенаправляет его вывод в nohup.out и предохраняет его от SIGHUP. Одним из эффектов (в честь которого и названа команда) является то, что процесс не получит любой отправленный NOHUP. Он абсолютно независим от контроля задач и может, в принципе, использоваться для задач на переднем плане (хотя это не особо полезно).

Если использовать вместе все три disown, nohup и &, то процесс будет запущен в фоне, удалён из контроля задач оболочки и эффективно отключён от терминала.

nohup выполняет КОМАНДУ игнорируя сигналы обрыва терминальной линии.

Возможные опции nohup:

Если стандартный ввод является терминалом, то он берётся из нечитаемого файла.

Если стандартный вывод является терминалом, то вывод добавляется в «nohup.out», если возможно, иначе в «$HOME/nohup.out».

Если стандартный поток ошибок является терминалом, то он перенаправляет в стандартный вывод. Чтобы записать вывод в ФАЙЛ, используйте «nohup КОМАНДА > ФАЙЛ».

ЗАМЕЧАНИЕ: ваша оболочка может предоставлять свою версию nohup, которая обычно перекрывает версию, описанную здесь. Пожалуйста, обращайтесь к документации по вашей оболочке, чтобы узнать, какие ключи она поддерживает.

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

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

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

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

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

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

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

Некоторая дополнительная информация:

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

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

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

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

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

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

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

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

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

Немного обо всем и все о немногом, или практический опыт системного администратора.

Июнь 2010
Пн Вт Ср Чт Пт Сб Вс
« Май Июль »
123456
78910111213
14151617181920
21222324252627
282930

Как отвязать процесс от терминала в Ubuntu

Calendar

18 июня 2010, 12:41

В лекции посвященной процессам и задачам в bash преподаватель рассказал нам о команде nohup, которая может защитить процесс от сигнала SIGHUP, который посылает своим дочерним процессам, процесс-родитель, когда завершает свою работу. Когда из текстовой консоли Linux или графического терминала (gnome-terminal) запускается команда, которая работает в фоне, то при закрытии терминала или выходе из консоли, команда также прекратит свою работу.

Если ближе к практике, то речь идет о следующем. Проведем эксперимент. Запускаем графический терминал (gnome-terminal) и пишем в нем команды:

$ nohup: ввод игнорируется, вывод добавляется в `nohup.out'

Здесь нажимаем Enter, чтобы вернуть приглашение терминала и пишем далее:

$ nohup: ввод игнорируется, вывод добавляется в `nohup.out'

disown [-ar] [-h] [jobspec . ]

Дальше несколько примеров. Открываем терминал и пишем команды:

$ gedit &
[1] 3371
$ jobs
[1]+ Running gedit &
$ disown %1
$ jobs

Команда jobs в третьей строке показывает, что в таблице заданий находится задание под номером 1. Команда disown %1 убирает это задание из таблицы. Следующей командой jobs проверяем, что действительно в таблице теперь нет заданий. После этого закрываем терминал и видим, что редактор gedit работает.

С ключом -h задания не будут удалятся из таблицы, но сигнал SIGHUP все равно обрабатывать не будут. Закроем gedit и выполним команды еще раз:

$ gedit &
[1] 3953
$ jobs
[1]+ Running gedit &
$ disown -h %1
$ jobs
[1]+ Running gedit &

Как видите задание осталось, в таблице, но если закрыть терминал, то все равно gedit будет работать. Запущенная без параметров команда disown удалит из таблицы заданий все задания. Дальше можете поэкспериментировать сами.

Также хочу добавить, что если из графического терминала в Ubuntu выходить по команде exit, то запущенные из терминала приложения останутся работать и без команд nohup или disown.

Чуть не забыл о браузере Opera :) С командой disown все работает так как нужно. То есть для того чтобы опера не закрывалась после закрытия графического терминала нужно после запуска команды выполнить команду disown:

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

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

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

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

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

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

Вы можете сразу начать процесс как фоновый, добавив в его конец символ "&":

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

Некоторая дополнительная информация:

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

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

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

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

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

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

Читайте также: