如何防止在 Linux 中关闭 SSH 客户端后停止后台进程[关闭]
- 2024-09-30 14:02:00
- admin 原创
- 159
问题描述:
我正在通过 SSH (Putty) 在 Linux 机器上工作。我需要让一个进程在夜间运行,所以我认为可以通过在后台启动该进程(在命令末尾使用 & 符号)并将 stdout 重定向到文件来实现。
令我惊讶的是,这不起作用。一旦我关闭 Putty 窗口,该过程就会停止。
我怎样才能防止这种情况发生?
解决方案 1:
检查“ nohup ”程序。
解决方案 2:
我建议使用GNU Screen。它允许您断开与服务器的连接,同时所有进程继续运行。在我知道它之前,我不知道没有它我该怎么生活。
解决方案 3:
当会话关闭时,进程会收到 SIGHUP 信号,但显然它没有捕获该信号。您可以在启动进程时使用该命令,或者在启动进程后使用nohup
bash 内置命令来防止这种情况发生: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 <<EOF
[...]
EOF
这适用于我尝试过的每个 shell,包括 busybox/etc (initramfs)。我以前从未见过这样做,我是在探索过程中独立发现的,谁知道 source 可以接受参数?但如果有这样的东西,它通常是一种更易于管理的 eval 形式。
解决方案 5:
nohup blah &
将你的进程名称替换为 blah!
解决方案 6:
就我个人而言,我喜欢‘批处理’命令。
$ batch
> mycommand -x arg1 -y arg2 -z arg3
> ^D
这会将其放入后台,然后将结果邮寄给您。它是 cron 的一部分。
解决方案 7:
对于大多数进程,你可以使用这个旧的 Linux 命令行技巧来进行伪守护进程化:
# ((mycommand &)&)
例如:
# ((sleep 30 &)&)
# exit
然后启动一个新的终端窗口并:
# ps aux | grep sleep
将显示sleep 30
仍在运行。
您所做的是将进程作为子进程的子进程启动,当您退出时,nohup
通常会触发进程退出的命令不会级联到孙进程,而是将其作为孤立进程,仍在运行。
我更喜欢这种“设置它并忘记它”的方法,无需处理nohup
、、screen
tmux、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 "echo $$ > $pidfile; exec $FOO_BIN $FOO_CONFIG " > /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 'sleep 30 >&- 2>&- <&- &'
# 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 <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
二进制可执行文件也可以使用 pm2 运行。您必须对 jason 文件进行更改。将 更改"exec_interpreter" : "node"
为"exec_interpreter" : "none".
(请参阅属性部分)。
#include <stdio.h>
#include <unistd.h> //No standard C library
int main(void)
{
printf("Hello World
");
sleep (100);
printf("Hello World
");
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是一个启动独立于会话的进程的好工具。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件