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

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

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

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

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

exec gnome-terminal -e "vim [email protected]" &> /dev/null & 

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

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

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

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

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


О, и, кстати, не используйте « [email protected] », где вы его используете.

[email protected] Означает, $1 , $2 , $3 …, который превратит вашу команду в:

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

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

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

 gnome-terminal -e "vim $(printf "%q " "[email protected]")" 
 nohup cmd & 

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

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

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

Читая эти ответы, я был под первым впечатлением, что выдача 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. Для многих пользователей может быть желательно увидеть, поддерживает ли ваша оболочка такую ​​возможность, как setopt nohup zsh. Это можно использовать, чтобы указать, что SIGHUP не следует отправлять заданиям в таблицу заданий при выходе оболочки. Вы можете применить это непосредственно перед выходом из оболочки или добавить ее в конфигурацию оболочки, например ~/.zshrc если вы ее всегда хотите.
  3. Найдите способ редактирования таблицы заданий. Я не мог найти способ сделать это в tcsh или csh , что несколько тревожит.
  4. Напишите небольшую программу C для форкирования и exec() . Это очень плохое решение, но источник должен состоять только из нескольких десятков строк. Затем вы можете передавать команды в качестве аргументов командной строки программе C и, таким образом, избегать записи, специфичной для процесса, в таблице заданий.
  1. Nohup $ COMMAND &

  2. $ COMMAND & disown

  3. Команда setsid

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

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

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

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

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

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

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

К этому:

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

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

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

(Команда) &

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

проверить –

 (sleep 100) & exit 

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

 ps aux | grep sleep 

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

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

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

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

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

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

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

 function run_disowned() { "[email protected]" & disown } function dos() { # run_disowned and silenced run_disowned "[email protected]" 1>/dev/null 2>/dev/null } 

Префикс команды с dos для ее отстранения от терминала.

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

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

 command & disown 

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

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

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

 #!/bin/bash TIMEOUT=0.1 CMD=( "[email protected]" ) #Could have some shortcuts here, eg replace "somefile.c" with "gedit somefile.c" #use nohup to run the command, suppressing its output and allowing the terminal to be closed #also send nohup's output to /dev/null, supressing nohup.out #run nohup in the background so this script doesn't block #print the command for debugging and to see bash variable expansion printf "%q " "${CMD[@]}" echo nohup "${CMD[@]}" >/dev/null 2>&1 & NOHUP_PID=$! #kill this script after a short time, exiting with success status - command is still running #this is needed as there is no timeout argument for `wait` below MY_PID=$$ trap "exit 0" SIGINT SIGTERM sleep $TIMEOUT && kill $MY_PID 2>/dev/null & #ignore "No such process" error if this exits normally #if the command finishes before the above timeout, everything may be just fine or there could have been an error wait $NOHUP_PID NOHUP_STATUS=$? #print an error if there was any. most commonly, there was a typo in the command [ $NOHUP_STATUS != 0 ] && echo "Error: $CMD" #return the exit status of nohup, whatever it was exit $NOHUP_STATUS 

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

 >>> run false false Error: false >>> echo $? 1 >>> run true true >>> run sleep 10 sleep 10 >>> 

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

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

 sudo apt-get install npm 

И для Redhat

 sudo yum install npm 

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

 npm install [email protected] -g 

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

 $ pm2 start app.js # Start, Daemonize and auto-restart application (Node) $ pm2 start app.py # Start, Daemonize and auto-restart application (Python) 

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

 $ pm2 list # List all processes started with PM2 $ pm2 monit # Display memory and cpu usage of each app $ pm2 show [app-name] # Show all informations about application 

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

 $ 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 #contain all applications logs 

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

  • Игнорировать все зависимости для конкретного пакета с помощью apt-get
  • Не удается смонтировать разделы NTFS из-за Windows 10?
  • Изменение размера разделов в mdadm RAID1
  • Как переустановить диспетчер загрузки Windows на раздел EFI
  • Ubuntu - удаление неиспользуемых ядер
  • Случайно rsync --delete, / usr влияет, любой способ проверить и переустановить отсутствующий компонент?
  • Схема раздела и размер для двойной загрузки Windows 7 и Ubuntu 9.10 с отдельными разделами для данных и / home
  • Установить зависимости для пакета dpkg?
  • Как поменять «fn» использование функциональных клавиш на Apple Keyboard в Linux
  • Запустить rsync с правами root на удаленной машине
  • Ubuntu не запускает Xorg после обновления до 9.10
  • Давайте будем гением компьютера.