Как закрыть терминал, не убив запущенную команду?
Иногда я хочу начать процесс и забыть об этом. Если я запустил его из командной строки, например:
красное смещение
Я не могу закрыть терминал, иначе он убьет процесс. Могу ли я запустить команду таким образом, чтобы я мог закрыть терминал, не убив процесс?
11 ответов
Одно из следующих 2 должно работать:
$ nohup redshift &
или
$ redshift &
$ disown
Подробнее о том, как это работает, см. ниже:
-
man nohup
-
help disown
-
Разница между nohup, disown и & (be обязательно прочитайте комментарии тоже)
Если ваша программа уже запущена , вы можете приостановить ее с помощью Ctrl-Z
, потяните ее в фоновом режиме с помощью bg
, а затем disown
, вот так:
$ sleep 1000
^ Z
[1] + остановка сна 1000
$ bg
$ disown
$ exit
Хороший ответ уже отправлен @StevenD, но я думаю, что это может прояснить его немного больше.
Причина, по которой процесс уничтожается при завершении терминала, заключается в том, что начатый процесс является дочерним процессом терминала. Как только вы закроете терминал, это также убьет эти дочерние процессы. Дерево процессов можно увидеть с помощью pstree
, например, при запуске kate &
в Konsole:
init- +
А»œa» € konsole⻀» ¬a»€ Баша» €»¬a» € Katea»€» €»€ 2 * [{кейт}]
â ", â", â "" "" pstree
â ", â" "â" € 2 * [{konsole}]
Чтобы завершить процесс kate
от konsole
при завершении konsole
, используйте nohup
с помощью команды, например:
nohup kate &
После закрытия konsole
, pstree
будет выглядеть так:
init- +
| -kate --- 2 * [{кейт}]
и kate
сохранится. :)
Альтернативой является использование screen
/tmux
/byobu
, который будет поддерживать работу оболочки независимо от терминала.
Вы можете запустить такой процесс в терминале
setsid process
Это запустит программу в новом сеансе. Как объяснено http://hanoo.org/index.php?article=run- программа-в-новый сеанс Linux
У меня есть сценарий:
-
Запустить произвольные команды в фоновом режиме
-
Остановить их от уничтожения в окне терминала
-
Подавить их вывод
-
Обрабатывает статус выхода
Я использую его главным образом для gedit
, evince
, inkscape
и т. д., что у всех много раздражающего вывода терминала. Если команда заканчивается до TIMEOUT
, то вместо нулевого значения возвращается статус выхода nohup.
#! /Bin /Баш
АУТ = 0,1
#use nohup для запуска команды, подавления ее выхода и закрытия терминала
# Также отправьте вывод nohup в /dev /null, подавив nohup.out
#run nohup в фоновом режиме, чтобы этот скрипт не блокировал
nohup "$ {@}"> /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 "Ошибка $ {@}"
# вернуть статус выхода nohup, что бы это ни было
выход $ NOHUP_STATUS
примеры ...
> > > запустить true & & успех эха || сбой эха
успех
> > > запустить false & & успех эха || сбой эха
Ошибка false
потерпеть неудачу
> > > run sleep 1000 & & успех эха || сбой эха
успех
> > > run notfound & & успех эха || сбой эха
Ошибка не найдена
потерпеть неудачу
Хотя все предложения хорошо работают, я нашел, что моя альтернатива - использовать screen
- программу, которая настраивает виртуальный терминал на вашем экране.
Возможно, вы начнете его с экрана -S session_name
. Экран можно установить практически на все производные от Linux и Unix. Нажатие Ctrl + A и (нижний регистр) C начнет второй сеанс. Это позволит вам переключаться между начальным сеансом, нажимая Ctrl + A и 0 или новый сеанс, нажав Ctrl + A и 1 . У вас может быть до десяти сеансов в одном терминале. Раньше я запускал сеанс на работе, возвращался домой, ssh в свою рабочую машину, а затем вызывал экран -d -R session_name
. Это приведет к повторному подключению к этому удаленному сеансу.
Единственный способ сделать это - закрыть команду stdin и background:
command <& - &
Тогда он не уйдет, когда вы покинете оболочку. Перенаправление stdout - это приятная дополнительная вещь.
Недостатком является то, что вы не можете сделать это после факта.
Вы можете настроить процесс (PID), чтобы не получать сигнал HUP при выходе из системы и закрытии сеанса терминала. Используйте следующую команду:
nohup -p PID
Вероятно, похоже на ответ, предложенный apolinsky , я использую вариант на экране . Команда ванили такая
экран bash -c 'long_running_command_here; эхо; read -p "ALL DONE:" '
Сессия может быть отключена с помощью Ctrl A Ctrl D и снова подключена в простейшем случае с экраном -r
. У меня это завернуто в скрипт под названием session
, который живет в моем PATH
, готовом для удобного доступа:
#! /Bin /Баш
#
если screen -ls | awk '$ 1 ~ /^[1-9][0-9]*\.'"$1"'/'> /dev /null
тогда
echo "ПРЕДУПРЕЖДЕНИЕ: сеанс уже запущен (повторное соединение с 'screen -r $ 1')"> & 2
еще
exec screen -S "$ 1" bash -c "$ @; echo; echo '--------------------'; read -p 'ALL DONE (Вход для выхода ):»
echo "ERROR: экран не установлен в этой системе"> & 2
фи
выход 1
Это работает только тогда, когда вы заранее знаете, что хотите отключить программу. Он не предусматривает отсоединение уже запущенной программы .
Я предпочитаю:
(applicationName &)
например:
linux @ linux-desktop: ~ $ (chromium-browser &)
Обязательно используйте скобки, когда введите команду!
Как и в других ранее опубликованных ответах, можно перевести текущий процесс, чтобы использовать «экран» ретроспективно благодаря reptyr , а затем закройте терминал. Этапы описаны в этом сообщении . Для этого выполните следующие действия:
- Приостановить процесс
- Возобновить процесс в фоновом режиме
- Отключить процесс
- Запустить сеанс экрана
- Найти PID процесса
- Используйте reptyr для выполнения процесса