如何防止在 Linux 中关闭 SSH 客户端后停止后台进程[关闭]

2024-09-30 14:02:00
admin
原创
159
摘要:问题描述:我正在通过 SSH (Putty) 在 Linux 机器上工作。我需要让一个进程在夜间运行,所以我认为可以通过在后台启动该进程(在命令末尾使用 & 符号)并将 stdout 重定向到文件来实现。令我惊讶的是,这不起作用。一旦我关闭 Putty 窗口,该过程就会停止。我怎样才能防止这种情况发生...

问题描述:

我正在通过 SSH (Putty) 在 Linux 机器上工作。我需要让一个进程在夜间运行,所以我认为可以通过在后台启动该进程(在命令末尾使用 & 符号)并将 stdout 重定向到文件来实现。

令我惊讶的是,这不起作用。一旦我关闭 Putty 窗口,该过程就会停止。

我怎样才能防止这种情况发生?


解决方案 1:

检查“ nohup ”程序。

解决方案 2:

我建议使用GNU Screen。它允许您断开与服务器的连接,同时所有进程继续运行。在我知道它之前,我不知道没有它我该怎么生活。

解决方案 3:

当会话关闭时,进程会收到 SIGHUP 信号,但显然它没有捕获该信号。您可以在启动进程时使用该命令,或者在启动进程后使用nohupbash 内置命令来防止这种情况发生:disown -h

> help disown
disown: disown [-h] [-ar] [jobspec ...]
     By default, removes each JOBSPEC argument from the table of active jobs.
    If the -h option is given, the job is not removed from the table, but is
    marked so that SIGHUP is not sent to the job if the shell receives a
    SIGHUP.  The -a option, when JOBSPEC is not supplied, means to remove all
    jobs from the job table; the -r option means to remove only running jobs.

解决方案 4:

守护进程?nohup?SCREEN?(tmux ftw,screen 是垃圾 ;-)

就像其他应用程序从一开始就做的事情一样——双重分叉。

# ((exec sleep 30)&)
# grep PPid /proc/`pgrep sleep`/status
PPid:   1
# jobs
# disown
bash: disown: current: no such job

砰!完成了 :-) 我已经在各种类型的应用程序和许多旧机器上无数次使用过它。您可以结合重定向等功能在您和进程之间打开一个私人通道。

创建为coproc.sh:

#!/bin/bash

IFS=

run_in_coproc () {
    echo "coproc[$1] -> main"
    read -r; echo $REPLY
}

# dynamic-coprocess-generator. nice.
_coproc () {
    local i o e n=${1//[^A-Za-z0-9_]}; shift
    exec {i}<> <(:) {o}<> >(:) {e}<> >(:)
. /dev/stdin <<COPROC "${@}"
    (("$@")&) <&$i >&$o 2>&$e
    $n=( $o $i $e )
COPROC
}

# pi-rads-of-awesome?
for x in {0..5}; do
    _coproc COPROC$x run_in_coproc $x
    declare -p COPROC$x
done

for x in COPROC{0..5}; do
. /dev/stdin <<RUN
    read -r -u ${$x[0]}; echo $REPLY
    echo "$x <- main" >&${$x[1]}
    read -r -u ${$x[0]}; echo $REPLY
RUN
done

进而

# ./coproc.sh 
declare -a COPROC0='([0]="21" [1]="16" [2]="23")'
declare -a COPROC1='([0]="24" [1]="19" [2]="26")'
declare -a COPROC2='([0]="27" [1]="22" [2]="29")'
declare -a COPROC3='([0]="30" [1]="25" [2]="32")'
declare -a COPROC4='([0]="33" [1]="28" [2]="35")'
declare -a COPROC5='([0]="36" [1]="31" [2]="38")'
coproc[0] -> main
COPROC0 <- main
coproc[1] -> main
COPROC1 <- main
coproc[2] -> main
COPROC2 <- main
coproc[3] -> main
COPROC3 <- main
coproc[4] -> main
COPROC4 <- main
coproc[5] -> main
COPROC5 <- main

然后,生成任何东西。<(:) 通过进程替换打开一个匿名管道,该管道会终止,但管道会保留下来,因为您有它的句柄。我通常会使用sleep 1而不是 ,:因为它有点不可靠,而且我会收到“文件繁忙”错误 - 如果运行的是真正的命令(例如,command true),则永远不会发生这种情况

“定界文档来源”:

. /dev/stdin &lt;&lt;EOF
[...]
EOF

这适用于我尝试过的每个 shell,包括 busybox/etc (initramfs)。我以前从未见过这样做,我是在探索过程中独立发现的,谁知道 source 可以接受参数?但如果有这样的东西,它通常是一种更易于管理的 eval 形式。

解决方案 5:

nohup blah &amp;

将你的进程名称替换为 blah!

解决方案 6:

就我个人而言,我喜欢‘批处理’命令。

$ batch
> mycommand -x arg1 -y arg2 -z arg3
> ^D

这会将其放入后台,然后将结果邮寄给您。它是 cron 的一部分。

解决方案 7:

对于大多数进程,你可以使用这个旧的 Linux 命令行技巧来进行伪守护进程化:

# ((mycommand &amp;)&amp;)

例如:

# ((sleep 30 &amp;)&amp;)
# exit

然后启动一个新的终端窗口并:

# ps aux | grep sleep

将显示sleep 30仍在运行。

您所做的是将进程作为子进程的子进程启动,当您退出时,nohup通常会触发进程退出的命令不会级联到孙进程,而是将其作为孤立进程,仍在运行。

我更喜欢这种“设置它并忘记它”的方法,无需处理nohup、、screentmux、I/o 重定向或任何类似的东西。

解决方案 8:

正如其他人所指出的,为了在后台运行一个进程,以便您可以断开与 SSH 会话的连接,您需要让后台进程正确地与其控制终端(即 SSH 会话使用的伪 tty)分离。

您可以在 Stevens 的《高级网络程序,第 1 卷,第 3 版》或 Rochkind 的《高级 Unix 编程》等书籍中找到有关守护进程的信息。

最近(过去几年)我不得不处理一个无法正确守护自身进程的顽固程序。最后我通过创建一个通用守护进程程序来解决这个问题 - 类似于 nohup,但具有更多可用控件。

Usage: daemonize [-abchptxV][-d dir][-e err][-i in][-o out][-s sigs][-k fds][-m umask] -- command [args...]
  -V          print version and exit
  -a          output files in append mode (O_APPEND)
  -b          both output and error go to output file
  -c          create output files (O_CREAT)
  -d dir      change to given directory
  -e file     error file (standard error - /dev/null)
  -h          print help and exit
  -i file     input file (standard input - /dev/null)
  -k fd-list  keep file descriptors listed open
  -m umask    set umask (octal)
  -o file     output file (standard output - /dev/null)
  -s sig-list ignore signal numbers
  -t          truncate output files (O_TRUNC)
  -p          print daemon PID on original stdout
  -x          output files must be new (O_EXCL)

在未使用 GNU getopt() 函数的系统上,双破折号是可选的;在 Linux 等系统中,它是必需的(或者您必须在环境中指定 POSIXLY_CORRECT)。由于双破折号在任何地方都适用,因此最好使用它。

如果您想要 的源代码,仍然可以联系我 (firstname dot lastname at gmail dot com) daemonize

但是,该代码现在(终于)可以在 GitHub 上的我的SOQ(Stack Overflow Questions)存储库中作为packages
子目录daemonize-1.10.tgz中的
文件使用。

解决方案 9:

在基于 Debian 的系统上(在远程机器上)安装:

sudo apt-get 安装 tmux

用法:

tmux

运行你想要的命令

重命名会话:

Ctrl+B然后$

设置名称

退出会话:

Ctrl+B然后D

(这将离开 tmux 会话)。然后,您可以退出 SSH。

当你需要返回/再次检查时,启动 SSH,然后输入

tmux 附加会话名称

它将带您回到您的 tmux 会话。

解决方案 10:

如果您使用 screen 以 root 身份运行进程,请警惕特权提升攻击的可能性。如果您自己的帐户以某种方式受到损害,将有直接的方法接管整个服务器。

如果此进程需要定期运行,并且您有足够的服务器访问权限,则更好的选择是使用 cron 运行该作业。您还可以使用 init.d(超级守护进程)在后台启动进程,并且它可以在完成后立即终止。

解决方案 11:

nohup如果您想将您的详细信息记录到文件中,这非常有用。但是当它进入后台时,如果您的脚本要求,您无法为其提供密码。我认为您必须尝试screen。它是一个实用程序,您可以在您的 Linux 发行版上使用 yum(例如在 CentOS 上),yum install screen然后通过 putty 或其他软件访问您的服务器,在您的 shell 类型中screen。它将在 putty 中打开屏幕 [0]。做你的工作。您可以在同一个 putty 会话中创建更多屏幕 [1]、屏幕 [2] 等。

您需要了解的基本命令:

开始屏幕

屏幕


创建一个屏幕

Ctrl+A+C


移动到您创建的下一个屏幕

Ctrl+A+N


分离

Ctrl+A+D


工作期间关闭你的 Putty。下次通过 Putty 登录时,请输入

屏幕-r

要重新连接到屏幕,您可以看到您的进程仍在屏幕上运行。要退出屏幕,请输入 #exit。

详情请参阅man screen

解决方案 12:

Nohup 允许在父进程被终止时不终止客户端进程,作为您注销时的参数。更好的方法是使用:

nohup /bin/sh -c &quot;echo $$ > $pidfile; exec $FOO_BIN $FOO_CONFIG  &quot; > /dev/null

Nohup 使您启动的进程不会终止,您的 SSH 会话及其子进程在您注销时会被终止。我给出的命令为您提供了一种将应用程序的 pid 存储在 pid 文件中的方法,以便您稍后可以正确地终止它,并允许进程在您注销后运行。

解决方案 13:

使用屏幕。它使用起来非常简单,并且像终端的 vnc 一样工作。http
://www.bangmoney.org/presentations/screen.html

解决方案 14:

还有开源 libslack 包的daemon命令。

daemon具有很高的可配置性,并且确实关心所有繁琐的守护进程事务,例如自动重启、日志记录或 pidfile 处理。

解决方案 15:

如果您也愿意运行 X 应用程序 - 请将xpra与“screen”一起使用。

解决方案 16:

我也会选择屏幕程序(我知道其他人的答案是屏幕,但这是一个完成)

不仅因为 &、ctrl+z bg disown、nohup 等可能会给你带来意外的惊喜,即当你注销时,作业仍然会被终止(我不知道为什么,但它确实发生在我身上,并且它并没有打扰它,因为我切换到使用屏幕,但我想 anthonyrisinger 解决方案作为双重分叉可以解决这个问题),而且屏幕比仅仅背景化具有很大的优势:

screen will background your process without losing interactive control to it

顺便说一句,这是一个我永远不会问的问题 :) ... 我从开始在任何 unix 中做任何事情时都使用 screen ... 我(几乎)从来没有在 unix/linux shell 中工作而不先启动 screen ... 我现在应该停下来,否则我会开始无休止地演示什么是好的 screen 以及它能为你做什么 ... 自己去查一下,这是值得的 ;)

解决方案 17:

将此字符串附加到您的命令:>&- 2>&- <&- &。>&- 表示关闭 stdout。2>&- 表示关闭 stderr。<&- 表示关闭 stdin。& 表示在后台运行。这也适用于通过 ssh 以编程方式启动作业:

$ ssh myhost &#039;sleep 30 >&amp;- 2>&amp;- &lt;&amp;- &amp;&#039;
# ssh returns right away, and your sleep job is running remotely
$

解决方案 18:

接受的答案建议使用nohup。我宁愿建议使用pm2 。与nohup相比,使用pm2有很多优点,例如保持应用程序处于活动状态、维护应用程序的日志文件以及许多其他功能。有关更多详细信息,请查看此处

要安装pm2,你需要下载npm。对于基于 Debian 的系统

sudo apt-get install npm

对于 Redhat

sudo yum install npm

或者你可以按照这些说明操作。安装npm后使用它来安装pm2

npm install pm2@latest -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

使用应用程序名称或进程 ID 管理进程或一起管理所有进程:

$ pm2 stop     &lt;app_name|id|&#039;all&#039;|json_conf>
$ pm2 restart  &lt;app_name|id|&#039;all&#039;|json_conf>
$ pm2 delete   &lt;app_name|id|&#039;all&#039;|json_conf>
     

日志文件可以在以下位置找到:

$HOME/.pm2/logs #contain all applications logs

二进制可执行文件也可以使用 pm2 运行。您必须对 jason 文件进行更改。将 更改&quot;exec_interpreter&quot; : &quot;node&quot;&quot;exec_interpreter&quot; : &quot;none&quot;.(请参阅属性部分)。

#include &lt;stdio.h>
#include &lt;unistd.h>  //No standard C library
int main(void)
{
    printf(&quot;Hello World
&quot;);
    sleep (100);
    printf(&quot;Hello World
&quot;);
   
    return 0;
}

编译上述代码

gcc -o hello hello.c  

并在后台使用 np2 运行它

pm2 start ./hello

解决方案 19:

我使用了 screen 命令。此链接详细介绍了如何执行此操作

https://www.rackaid.com/blog/linux-screen-tutorial-and-how-to/#starting

解决方案 20:

在 systemd/Linux 上,systemd-run是一个启动独立于会话的进程的好工具。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用