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

<p>иногда я хочу начать процесс и забыть об этом. если я запускаю его из командной строки, вот так:</p><pre><code>redshift </code></pre><p>я не могу закрыть терминал, иначе он убьет процесс. могу ли я выполнить команду таким образом, чтобы я мог закрыть терминал, не прерывая процесс?</p>

<p>один из следующих 2 должен работать:</p><pre><code>$ nohup redshift & или$ redshift & $ disown ниже приведено немного больше информации о том, как это работает:  man nohup   help disown    <a href="https://unix.stackexchange.com/questions/3886/difference-between-nohup-disown-and">разница между nohup, disown и & (обязательно прочитайте также комментарии)  

если ваша программа уже запущена вы можете приостановить ее с помощью ctrl-z, перетащите его в фон с помощью bg, а затем disown, вот так:$ sleep 1000 ^z [1]+ stopped sleep 1000 $ bg $ disown $ exit 

хороший ответ уже опубликован @stevend, но я думаю, что это могло бы прояснить это немного больше.причиной того, что процесс завершается при завершении терминала, является то, что запускаемый вами процесс является дочерним процессом терминала. как только вы закроете терминал, это также уничтожит эти дочерние процессы. вы можете увидеть дерево процессов с помощью pstree, например, при запуске kate & в konsole:init-+ ├─konsole─┬─bash─┬─kate───2[{kate}] │ │ └─pstree │ └─2[{konsole}] чтобы отключить процесс kate от konsole после завершения konsole, используйте команду nohup с командой, например:nohup kate & после закрытия konsole, pstree будет выглядеть так:init-+ |-kate---2[{kate}] и kate выживет. :)альтернативой является использование screen/tmux/byobu, которое будет поддерживать работу оболочки независимо от терминала.

вы можете запустить процесс, как это в терминалеsetsid processэто запустит программу в новом сеансе. как объяснено <a href="http://hanoo.org/index.php?article=run-program-in-new-session-linux">http://hanoo.org/index.php?article=run-program-in-new-session-linux 

хотя все предложения работают хорошо, я обнаружил, что моя альтернатива - использовать screen, программу, которая настраивает виртуальный терминал на вашем экране.вы можете начать с screen -s session_name. экран может быть установлен практически на все производные linux и unix. удары ctrl+a и (нижний регистр) c начнется второй сеанс. это позволит вам переключаться между начальным сеансом, нажимая ctrl+a а также  или новый сеанс, нажав ctrl+a а также 1, вы можете иметь до десяти сеансов в одном терминале. я использовал, чтобы начать сеанс на работе, пойти домой, ssh на мою рабочую машину, а затем вызвать screen -d -r session_name. это соединит вас с этим удаленным сеансом.

я предпочитаю:(имя приложения и)например: linux@linux-desktop:~$ (chromium-browser &)</code></p><p>обязательно используйте скобки при вводе команды!</p>

<p>у меня есть скрипт для:</p><ul> <li> <h2>запускать произвольные команды в фоновом режиме</h2> </li> <li> <h2>остановите их от уничтожения с помощью окна терминала</h2> </li> <li> <h2>подавить их вывод</h2> </li> <li> <h2>обрабатывает статус выхода</h2> </li> </ul><p>я использую его в основном для <code>gedit</code>, <code>evince</code>, <code>inkscape</code> и т.д., которые все имеют много раздражающего вывода терминала. если команда завершается до <code>timeout</code>, вместо нуля возвращается состояние выхода nohup.</p><pre><code>#!/bin/bash timeout=0.1 #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 nohup "${@}" >/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 ${@}" #return the exit status of nohup, whatever it was exit $nohup\_status </code></pre><p>примеры...</p><pre><code>>>> run true && echo success || echo fail success >>> run false && echo success || echo fail error false fail >>> run sleep 1000 && echo success || echo fail success >>> run notfound && echo success || echo fail error notfound fail </code></pre>

<p>единственный способ сделать это в shell - закрыть команду stdin и выполнить команду background:</p><pre><code>command <&- & </code></pre><p>тогда он не выйдет, когда вы выйдете из shell. перенаправление stdout - хорошая дополнительная опция.</p><p>недостатком является то, что вы не можете сделать это после факта.</p>

<p>вы можете настроить процесс (pid) так, чтобы он не получал сигнал hup после выхода из системы и закрытия сеанса терминала. используйте следующую команду:</p><pre><code>nohup -p pid </code></pre>

<p>возможно, похоже на <a href="https://unix.stackexchange.com/a/185605/100397">ответ, предложенный apolinsky</a> , я использую вариант на <code>screen</code>. ванильная команда такая</p><pre><code>screen bash -c 'long\_running\_command\_here; echo; read -p "all done:"' </code></pre><p>сеанс может быть отключен с <kbd>ctrl a</kbd><kbd>ctrl d</kbd> и переподключил в простом случае с <code>screen -r</code>. я завернул это в скрипт с именем <code>session</code>, который находится в моем <code>path</code>, готовый для удобного доступа:</p><pre><code>#!/bin/bash # if screen -ls | awk '$1 ~ /^[1-9][0-9].'"$1"'/' >/dev/null then echo "warning: session is already running (reattach with 'screen -r $1')" >&2 else exec screen -s "$1" bash -c "$@; echo; echo '--------------------'; read -p 'all done (enter to exit):'" echo "error: 'screen' is not installed on this system" >&2 fi exit 1 </code></pre><p>это работает только тогда, когда вы заранее знаете, что хотите отключить программу. он не предусматривает <em> уже запущенную </em> программу для отключения.</p>

<p>подобно другим ответам, опубликованным ранее, можно передать запущенный процесс для ретроспективного использования "экрана" благодаря <a href="https://github.com/nelhage/reptyr">reptyr</a> , а затем закрыть терминал. шаги описаны в этом <a href="https://www.linkedin.com/pulse/move-running-process-screen-bruce-werdschinski">post</a> . шаги, которые необходимо предпринять:</p><ol> <li>приостановить процесс</li> <li>возобновить процесс в фоновом режиме</li> <li>отказаться от процесса</li> <li>запустите сеанс экрана</li> <li>найти pid процесса</li> <li>используйте reptyr, чтобы взять на себя процесс</li> </ol>