Как закрыть терминал, не убив запущенную команду?

Иногда я хочу начать процесс и забыть об этом. Если я запустил его из командной строки, например:

красное смещение

Я не могу закрыть терминал, иначе он убьет процесс. Могу ли я запустить команду таким образом, чтобы я мог закрыть терминал, не убив процесс?

248 голосов | спросил Matthew Pirocchi 13 62010vEurope/Moscow11bEurope/MoscowSat, 13 Nov 2010 01:57:08 +0300 2010, 01:57:08

11 ответов


258

Одно из следующих 2 должно работать:

$ nohup redshift &

или

$ redshift &
$ disown

Подробнее о том, как это работает, см. ниже:

ответил Steven D 13 62010vEurope/Moscow11bEurope/MoscowSat, 13 Nov 2010 02:30:23 +0300 2010, 02:30:23
126

Если ваша программа уже запущена , вы можете приостановить ее с помощью Ctrl-Z, потяните ее в фоновом режиме с помощью bg, а затем disown, вот так:

$ sleep 1000
^ Z
[1] + остановка сна 1000
$ bg
$ disown
$ exit
ответил Stefan 13 62010vEurope/Moscow11bEurope/MoscowSat, 13 Nov 2010 08:36:03 +0300 2010, 08:36:03
36

Хороший ответ уже отправлен @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, который будет поддерживать работу оболочки независимо от терминала.

ответил gertvdijk 5 WedEurope/Moscow2012-12-05T15:31:14+04:00Europe/Moscow12bEurope/MoscowWed, 05 Dec 2012 15:31:14 +0400 2012, 15:31:14
22

Вы можете запустить такой процесс в терминале

setsid process

Это запустит программу в новом сеансе. Как объяснено http://hanoo.org/index.php?article=run- программа-в-новый сеанс Linux

ответил hanoo 30 +04002012-10-30T09:55:12+04:00312012bEurope/MoscowTue, 30 Oct 2012 09:55:12 +0400 2012, 09:55:12
6

У меня есть сценарий:

  • Запустить произвольные команды в фоновом режиме

  • Остановить их от уничтожения в окне терминала

  • Подавить их вывод

  • Обрабатывает статус выхода

Я использую его главным образом для 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 & & успех эха || сбой эха
Ошибка не найдена
потерпеть неудачу
ответил jozxyqk 15 FebruaryEurope/MoscowbSat, 15 Feb 2014 08:12:02 +0400000000amSat, 15 Feb 2014 08:12:02 +040014 2014, 08:12:02
6

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

Возможно, вы начнете его с экрана -S session_name . Экран можно установить практически на все производные от Linux и Unix. Нажатие Ctrl + A и (нижний регистр) C начнет второй сеанс. Это позволит вам переключаться между начальным сеансом, нажимая Ctrl + A и 0 или новый сеанс, нажав Ctrl + A и 1 . У вас может быть до десяти сеансов в одном терминале. Раньше я запускал сеанс на работе, возвращался домой, ssh в свою рабочую машину, а затем вызывал экран -d -R session_name . Это приведет к повторному подключению к этому удаленному сеансу.

ответил apolinsky 19 FebruaryEurope/MoscowbThu, 19 Feb 2015 02:07:53 +0300000000amThu, 19 Feb 2015 02:07:53 +030015 2015, 02:07:53
5

Единственный способ сделать это - закрыть команду stdin и background:

command <& - &

Тогда он не уйдет, когда вы покинете оболочку. Перенаправление stdout - это приятная дополнительная вещь.

Недостатком является то, что вы не можете сделать это после факта.

ответил w00t 14 MaramFri, 14 Mar 2014 08:55:20 +04002014-03-14T08:55:20+04:0008 2014, 08:55:20
2

Вы можете настроить процесс (PID), чтобы не получать сигнал HUP при выходе из системы и закрытии сеанса терминала. Используйте следующую команду:

nohup -p PID
ответил tony 18 FebruaryEurope/MoscowbThu, 18 Feb 2016 08:30:07 +0300000000amThu, 18 Feb 2016 08:30:07 +030016 2016, 08:30:07
2

Вероятно, похоже на ответ, предложенный 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

Это работает только тогда, когда вы заранее знаете, что хотите отключить программу. Он не предусматривает отсоединение уже запущенной программы .

ответил roaima 29 MarpmTue, 29 Mar 2016 18:10:16 +03002016-03-29T18:10:16+03:0006 2016, 18:10:16
2

Я предпочитаю:

(applicationName &)

например: linux @ linux-desktop: ~ $ (chromium-browser &)

Обязательно используйте скобки, когда введите команду!

ответил daGo 2 MarpmWed, 02 Mar 2016 14:15:58 +03002016-03-02T14:15:58+03:0002 2016, 14:15:58
1

Как и в других ранее опубликованных ответах, можно перевести текущий процесс, чтобы использовать «экран» ретроспективно благодаря reptyr , а затем закройте терминал. Этапы описаны в этом сообщении . Для этого выполните следующие действия:

  1. Приостановить процесс
  2. Возобновить процесс в фоновом режиме
  3. Отключить процесс
  4. Запустить сеанс экрана
  5. Найти PID процесса
  6. Используйте reptyr для выполнения процесса
ответил user308879 1 Maypm18 2018, 23:15:38

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

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

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