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

IgorKa — Информационный ресурс

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

Июнь 2010
Пн Вт Ср Чт Пт Сб Вс
« Май Июль »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

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

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

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

В результате будут запущены два графических приложения: калькулятор и редактор. Теперь закроем терминал нажав на кнопку закрытия (”крестик”). Как видите вместе с терминалом завершили работу и приложения запущенные из него. Снова открываем терминал и пишем такие команды:

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

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

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

И также нажимаем Enter. Теперь снова закрываем терминал, нажав на “крестик”. Теперь приложения остались работать и не закрылись. Команду nohup можно использовать, но есть приложения с которыми она не срабатывает. Например, браузер Opera. Набрав, nohup opera & и закрыв терминал, Opera также завершит свою работу.

В оболочке bash есть встроенная команда, которая больше подходит для требуемой задачи. Это команда disown. Приложения запущенные в терминале в фоне (приложения запущенные со знаком &), являются задачами или заданиями (jobspec в мане), которые формируют таблицу заданий. При выходе из терминала bash просматривает эту таблицу и посылает всем заданиям сигнал SIGHUP. Команда disown занимается тем, удаляет задания из таблицы заданий. Посмотреть информацию о команде disown можно в справке man bash. На всякий случай процитирую здесь фрагмент из справки:

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

Without options, each jobspec is removed from the table of active jobs. If jobspec is not present, and neither -a nor -r is supplied, the shell’s notion of the current job is used. If the -h option is given, each jobspec is not removed from the table, but is marked so that SIGHUP is not sent to the job if the shell receives a SIGHUP. If no jobspec is present, and neither the -a nor the -r option is supplied, the current job is used. If no jobspec is supplied, the -a option means to remove or mark all jobs; the -r option without a jobspec argument restricts operation to running jobs. The return value is 0 unless a jobspec does not specify a valid job.

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

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

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

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

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

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

Теперь если нажать на “крестик”, то после закрытия терминала, браузер будет работать.

Источник

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

Некоторые программы, например, opera, «захватывают» терминал, в котором запущены.
Пробую это сделать:
# ps -A | grep opera
4107 pts/3 00:01:29 opera
4186 pts/3 00:00:00 opera
# disown 4107
vadim$ disown 4107
bash: disown: 4107: no such job
:-(((

Re: Как »отвязать» процесс от терминала?

запускай $ opera& — и терминал останеться свободным, а если хочешь чтобы и после закрытия терминала приложение оставалось запущенным $ nohup opera&

Re: Как »отвязать» процесс от терминала?

> запускай $ opera& — и терминал останеться свободным, а если хочешь чтобы и после закрытия терминала приложение оставалось запущенным $ nohup opera&
А ещё можно, чтоб «после закрытия терминала приложение оставалось запущенным» просто не «давить сдуру» на кнопку «закрыть», а так «мягонько» попросить
$ exit

Re: Как »отвязать» процесс от терминала?

Дык это я знаю. Мне именно запущенный процес нужно отвязать.

Re: Как »отвязать» процесс от терминала?

> # ps -A | grep opera
> 4107 pts/3 00:01:29 opera
> 4186 pts/3 00:00:00 opera
> # disown 4107
> vadim$ disown 4107
> bash: disown: 4107: no such job

Во-первых, параметр ‘-A’ для ps — лишний! ( попробуйте без него 😉 )

Во-вторых, попробуйте ещё
$ jobs | grep opera
[1]+ Running opera &
$ disown %1

В-третьих, делайте чтоб у вас в консоли указатель был $, а не # — под рутом работать плохо.

Re: Как »отвязать» процесс от терминала?

Проблема в том, что программа ПОЛНОСТЬЮ захватила терминал. Т. е., запустите gimp и попробуйте понабивать команды в его терминале. Не получиться. В этом-то и проблема! 😎 Ключ -А для этого и нужен — чтобы с —другого— терминала видеть процесс с другого.

Re: Как »отвязать» процесс от терминала?

А, вы без «&» запускате — так бы сразу и сказали (а без «&» терминал захватит _любая_ программа на время выполнения).
Тогда конечно, disown не поможет.

Re: Как »отвязать» процесс от терминала?

Не знаю как только «отвязать» процесс от терминала, но как прибить этот самый терминал без убийства запущенного приложения нашёл — например так:
kill -4

Re: Как »отвязать» процесс от терминала?

>что программа ПОЛНОСТЬЮ захватила терминал.

Может помочь: соседнего терминала kill -STOP, потом с этого bg ; disown.

Re: Как »отвязать» процесс от терминала?

Для запуска GUI-приложений воспользуйся grun (gtk2) или xexec (qt)
Настрой свой wm на запуск grun/xexec по hotkey

Re: Как »отвязать» процесс от терминала?

Вообще, всё же хочется заметить, что у вопрошающего в корне неверное представление о процессе:
не программы «захватывают» терминал, а обратно shell ( и терминал тут вообще не причём 😉 ) ждёт окончания завершения программы. Чтоб не ждал как раз и нужен запуск в foreground.

Источник

Как запустить процесс в фоне Linux

Как правило, выполнение команд в терминале связано с одним неудобством — прежде чем приступить к вводу следующей команды, следует дождаться выполнения предыдущей. Это происходит, поскольку текущий процесс блокирует доступ к оболочке операционной системы и в таких случаях говорят, что команда выполняется на переднем плане. Что же делать, если нужно запустить несколько команд одновременно? Есть несколько решений. Первое и наиболее очевидное — открыть дополнительное окно терминала. Второе — инициировать выполнение команды в фоновом режиме.

Если какой-либо процесс происходит в фоновом режиме, это значит, что он не предусматривает взаимодействия с пользователем, следовательно, доступ к оболочке остается свободным. Прочитав эту статью, вы узнаете как запустить процесс в фоне Linux и что делать, чтобы их выполнение не прерывалось после закрытия терминала.

Как запустить процесс в фоне Linux

Для выполнения команды в фоновом режиме достаточно добавить в конце символ амперсанда (&):

В выводе терминала будут отображены порядковый номер задачи (в квадратных скобках) и идентификатор процесса:

В фоновом режиме можно одновременно запускать сразу два, три, четыре процесса и даже больше.

Работая в фоновом режиме, команда все равно продолжает выводить сообщения в терминал, из которого была запущена. Для этого она использует потоки stdout и stderr, которые можно закрыть при помощи следующего синтаксиса:

command > /dev/null 2>&1 &

Здесь >/dev/null 2>&1 обозначает, что stdout будет перенаправлен на /dev/null, а stderr — к stdout.

Узнать состояние всех остановленных и выполняемых в фоновом режиме задач в рамках текущей сессии терминала можно при помощи утилиты jobs c использованием опции -l:

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

В любое время можно вернуть процесс из фонового режима на передний план. Для этого служит команда fg:

Если в фоновом режиме выполняется несколько программ, следует также указывать номер. Например:

Для завершения фонового процесса применяют команду kill с номером программы:

Как перевести процесс в фоновый режим

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

  1. Остановить выполнение команды, нажав комбинацию клавиш Ctrl+Z.
  2. Перевести процесс в фоновый режим при помощи команды bg.

Работа процессов в фоне

Запуск скрипта в фоне linux — это одно, но надо чтобы он ещё работал после закрытия терминала. Закрытие терминала путем нажатия на крестик в верхнем углу экрана влечет за собой завершение всех фоновых процессов. Впрочем, есть несколько способов сохранить их после того как связь с интерактивной оболочкой прервется. Первый способ — это удаление задачи из очереди заданий при помощи команды disown:

Как и в предыдущих случаях, при наличии нескольких одновременно выполняемых процессов следует указывать номер того, относительно которого будет выполнено действие:

Убедиться, что задачи больше нет в списке заданий, можно, использовав уже знакомую утилиту jobs -l. А чтобы просмотреть перечень всех запущенных процессов (в том числе и отключенных) применяется команда

Второй способ сохранить запущенные процессы после прекращения работы терминала — команда nohup. Она выполняет другую команду, которая была указана в качестве аргумента, при этом игнорирует все сигналы SIGHUP (те, которые получает процесс при закрытии терминала). Для запуска команды в фоновом режиме нужно написать команду в виде:

Как видно на скриншоте, вывод команды перенаправляется в файл nohup.out. При этом после выхода из системы или закрытия терминала процесс не завершается. Существует ряд программ, которые позволяют запускать несколько интерактивных сессий одновременно. Наиболее популярные из них — Screen и Tmux.

  • Screen либо GNU Screen — это терминальный мультиплексор, который позволяет запустить один рабочий сеанс и в рамках него открыть любое количество окон (виртуальных терминалов). Процессы, запущенные в этой программе, будут выполняться, даже если их окна невидимы или программа прекратила работу.
  • Tmux — более современная альтернатива GNU Screen. Впрочем, возможности Tmux не имеют принципиальных отличий — в этой программе точно так же можно открывать множество окон в рамках одного сеанса. Задачи, запущенные в Tmux, продолжают выполняться, если терминал был закрыт.

Выводы

Чтобы запустить скрипт в фоне linux, достаточно добавить в конце знак &. При запуске команд в фоновом режиме отпадает необходимость дожидаться завершения одной команды для того, чтобы ввести другую. Если у вас возникли вопросы, обязательно задавайте их в комментариях.

Источник

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

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

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

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

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

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

18 ответов 18

Прежде всего; как только вы начали процесс, вы можете запустить его в фоновом режиме, сначала остановив (нажав 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 & ), на самом деле вы ничего не можете сделать.

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

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

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

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

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

nohup отключает процесс (демонизирует его)

Если вы используете bash , попробуйте disown [jobspec] ; см Баш (1).

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

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

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

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

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

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

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

  1. screen и tmux могут решить эту проблему, но они гораздо тяжелее, и мне не нравится запускать их для такой простой задачи. Они гораздо больше подходят для ситуаций, в которых вы хотите поддерживать tty, как правило, на удаленной машине.
  2. Для многих пользователей может быть желательно посмотреть, поддерживает ли ваша оболочка такую возможность, как zsh setopt nohup . Это может использоваться для указания того, что SIGHUP не следует отправлять заданиям в таблице заданий при выходе из оболочки. Вы можете либо применить это непосредственно перед выходом из оболочки, либо добавить его в конфигурацию оболочки, например

/.zshrc если вы всегда хотите его включить .

  • Найдите способ отредактировать таблицу вакансий. Я не мог найти способ сделать это в tcsh или csh , что несколько беспокоит.
  • Напишите небольшую программу на C для разветвления и exec() . Это очень плохое решение, но источник должен состоять только из пары десятков строк. Затем вы можете передавать команды в качестве аргументов командной строки в программу C и, таким образом, избегать записи, специфичной для процесса, в таблице заданий.
  • Источник

    Читайте также:  Как будет развиваться windows
    Оцените статью