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

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

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

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

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

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

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

272 голоса | спросил AnC 23 MarpmMon, 23 Mar 2009 14:59:25 +03002009-03-23T14:59:25+03:0002 2009, 14:59:25

18 ответов


307

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

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

firefox &

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

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

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

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

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 ..., который превратит вашу команду в

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

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

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

gnome-terminal -e "vim $ (printf"% q "" $ @ ")"
ответил lhunath 23 MarpmMon, 23 Mar 2009 16:18:35 +03002009-03-23T16:18:35+03:0004 2009, 16:18:35
190
nohup cmd &

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

ответил dsm 23 MarpmMon, 23 Mar 2009 15:17:32 +03002009-03-23T15:17:32+03:0003 2009, 15:17:32
51

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

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

ответил Randy Proctor 23 MarpmMon, 23 Mar 2009 15:05:02 +03002009-03-23T15:05:02+03:0003 2009, 15:05:02
34

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

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


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

& л; команда > & Амп;
отрекаться

или

& л; команда > & Амп ;; отрекаться

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

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

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

  1. screen и tmux могут решить эту проблему, но это гораздо более тяжелые весовые решения, и мне не нравится запускать их для такой простой задачи. Они гораздо более подходят для ситуаций, в которых вы хотите поддерживать tty, как правило, на удаленной машине.
  2. Для многих пользователей может быть желательно увидеть, поддерживает ли ваша оболочка такую ​​возможность, как zsh's setopt nohup. Это можно использовать для указания, что SIGHUP не следует отправлять заданиям в таблице заданий при выходе оболочки. Вы можете применить это непосредственно перед выходом из оболочки или добавить ее в конфигурацию оболочки, например, ~ /.zshrc, если вы ее всегда хотите.
  3. Найдите способ редактирования таблицы заданий. Я не мог найти способ сделать это в tcsh или csh, что несколько беспокоит.
  4. Напишите небольшую программу C для вилки и exec (). Это очень плохое решение, но источник должен состоять только из пары десятков строк. Затем вы можете передавать команды в качестве аргументов командной строки программе C и, таким образом, избегать записи, специфичной для процесса, в таблице заданий.
ответил Stephen Rosen 22 Jpm1000000pmWed, 22 Jan 2014 21:08:16 +040014 2014, 21:08:16
23
  1. nohup $ COMMAND &

  2. $ COMMAND & открестился

  3. команда setsid

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

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

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

ответил Mr. Minty Fresh 25 PM00000050000003131 2015, 17:39:31
9

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

ответил 25 MaramWed, 25 Mar 2009 04:51:05 +03002009-03-25T04:51:05+03:0004 2009, 04:51:05
8

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

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

> вакансии # ничего не показывает
> firefox &
> работы
[1] + Запуск Firefox

Для этого:

> вакансии # ничего не показывает
> (firefox &)
> # пока ничего не показывает
>

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

ответил Nathan Fellman 23 MarpmMon, 23 Mar 2009 17:55:15 +03002009-03-23T17:55:15+03:0005 2009, 17:55:15
6

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

(команда) & амп;

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

check -

(sleep 100) & Выход

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

ps aux | Спящий сон

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

ответил jitendra 7 AM00000090000002531 2012, 09:18:25
6

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

command & отрекаться

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

ответил ManuelSchneid3r 5 Maypm17 2017, 14:55:05
4

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

ответил Ben 23 MarpmMon, 23 Mar 2009 15:03:50 +03002009-03-23T15:03:50+03:0003 2009, 15:03:50
4

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

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

./script.sh
# приостановить процесс
{Ctrl-Z}
# фоновый процесс
Б.Г.
# список всех заданных заданий
работы
# вернуть его на передний план
фг
ответил djangofan 23 Mayam13 2013, 03:00:56
2

Попробуйте демон - должен быть доступен у вашего дружелюбного менеджера пакетов и всесторонне заботиться о каждом способе отсоединившись от терминала.

ответил ShiDoiSi 23 MarpmMon, 23 Mar 2009 15:10:49 +03002009-03-23T15:10:49+03:0003 2009, 15:10:49
1

В моем .bashrc у меня есть эти функции для этой цели:

function run_disowned () {
    «$ @» & отрекаться
}

function dos () {
    # run_disowned и отключен

    run_disowned "$ @" 1> /dev /null 2 ​​> /dev /null
}

Префикс команды dos, чтобы отделить ее от терминала.

Функция записывается для работы с bash и zsh.

ответил mic_e 14 J0000006Europe/Moscow 2015, 20:53:47
0

Я нашел в Mac OS X, что мне нужно использовать nohup И отключить, чтобы гарантировать, что дочерний процесс не будет разорван с помощью терминала.

ответил aaron 19 J0000006Europe/Moscow 2010, 20:46:44
0

Для этого я использую следующий скрипт. Он останавливает печать процесса на терминале, отсоединяется с помощью nohup и выходит из состояния возврата, если команда заканчивается в TIMEOUT.

#! /Bin /Баш

АУТ = 0,1

CMD = ("$ @")
# Здесь могут быть некоторые ярлыки, например. замените "somefile.c" на "gedit somefile.c"

#use nohup для запуска команды, подавления ее выхода и закрытия терминала
# Также отправьте вывод nohup в /dev /null, подавив nohup.out
#run nohup в фоновом режиме, чтобы этот скрипт не блокировал
#print команду для отладки и увидеть расширение переменной bash
printf "% q" "$ {CMD [@]}"
эхо
nohup "$ {CMD [@]}"> /dev /null 2 ​​& 1 &
NOHUP_PID = $!

#kill этот скрипт через короткое время, выход из состояния успеха - команда все еще запущена
#this необходимо, так как нет аргумента тайм-аута для `wait` ниже
MY_PID = $$
ловушка «выход 0» SIGINT SIGTERM
sleep $ TIMEOUT & & kill $ MY_PID 2> /dev /null & #ignore «Нет такого процесса», если это нормально

# Если команда заканчивается до указанного выше таймаута, все может быть просто замечательно или может быть ошибка
wait $ NOHUP_PID
NOHUP_STATUS = $?
#print ошибка, если она есть. чаще всего в команде была опечатка
[$ NOHUP_STATUS! = 0] & & & echo "Ошибка: $ CMD"
# вернуть статус выхода nohup, что бы это ни было
выход $ NOHUP_STATUS

Пример использования:

> > > запустить false
ложный
Ошибка: false
> > > echo $?
1
> > > запустить true
правда
> > > запустить сон 10
сон 10
> > >
ответил jozxyqk 21 stEurope/Moscowp30Europe/Moscow09bEurope/MoscowSun, 21 Sep 2014 08:42:43 +0400 2014, 08:42:43
0

Просто добавьте это в свой bashrc /zshrc:

detach () {
  "$ @" 1> /dev /null 2 ​​> /dev /null & amp ;; отрекаться
}

Затем вы можете запускать отмененные команды следующим образом:

отсоединить gedit ~ /.zshrc
ответил B. Branchard 5 FebruaryEurope/MoscowbMon, 05 Feb 2018 19:14:17 +0300000000pmMon, 05 Feb 2018 19:14:17 +030018 2018, 19:14:17
-1

Многие ответы предлагаются с использованием nohup . Я предпочел бы использовать pm2 . Использование pm2 поверх nohup имеет много преимуществ, таких как сохранение приложения в активном состоянии, сохранение файлов журналов для приложения и множество других функций. Для более подробной информации проверьте это .

Чтобы установить pm2 , вам нужно скачать npm . Для системы на базе Debian

sudo apt-get install npm

и для Redhat

sudo yum install npm

Или вы можете следовать этой инструкции . После установки npm используйте его для установки pm2

npm install pm2 @ last -g

После его завершения вы можете запустить приложение

$ pm2 start app.js # Запустить, Daemonize и автоматически перезапустить приложение (Node)
$ pm2 start app.py # Пуск, Daemonize и приложение автоматического перезапуска (Python)

Для мониторинга процесса используйте следующие команды:

$ pm2 list # Список всех процессов, запущенных с PM2
$ pm2 monit # Отображать память и использование процессора в каждом приложении
$ pm2 показать [app-name] # Показать всю информацию о приложении

Управление процессами с использованием имени приложения или идентификатора процесса или управления всеми процессами вместе:

$ pm2 stop <app_name | id | 'all' | json_conf>
$ pm2 restart <app_name | id | 'all' | json_conf>
$ pm2 delete <app_name | id | 'all' | json_conf>

Файлы журнала можно найти в

$ HOME /.pm2 /logs # содержать все журналы приложений
ответил haccks 15 FebruaryEurope/MoscowbWed, 15 Feb 2017 07:16:48 +0300000000amWed, 15 Feb 2017 07:16:48 +030017 2017, 07:16:48
-1

Если ваша цель - просто запустить приложение командной строки, не закрывая окно терминала, тогда вы можете попробовать запустить приложение после запуска терминала с помощью alt-F2.

ответил MattKelly 5 PMpWed, 05 Apr 2017 16:47:37 +030047Wednesday 2017, 16:47:37

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132