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

令我惊讶的是,这行不通。一旦我关闭腻子窗口,该过程就会停止。

如何防止这种情况发生?

#1 楼

查看“ nohup”程序。

评论


之后如何停止?

–德里克·达默(Derek Dahmer)
2010年7月13日在17:49

登录并执行“ kill ”。如果您不知道pid,请使用“ pidof”。

– JesperE
2010年7月13日在18:01

您可以使用nohup命令> / dev / null 2>&1&在后台运行,而无需创建任何stdout或stderr输出(没有nohup.out文件)

– KCD
13年4月1日在23:03

由于我懒惰且不善于记住字符的隐含序列,因此我根据@KCD所说的内容编写了此代码,并且已经使用了很多。

–异常
15年10月31日在22:20

这在我这边不起作用,因为这不会在关闭ctty时阻止程序获取SIGHUP。我有一个永远不会收到SIGHUP的程序。 nohup不起作用,因为它不能阻止SIGHUP,它只是默认情况下忽略它,这不必占优势。由于我既没有屏幕,也没有tmux,也没有类似的文件,因此,我需要一种在Shell级别上确定从ctty取消程序关联的方法。我发现的唯一方法是用ssh -T remote'(program&)&'启动该程序的黑客,这使得无法在交互式ssh会话中后台程序。

– Tino
17年2月28日在8:25

#2 楼

我建议使用GNU屏幕。它允许您在所有进程继续运行时与服务器断开连接。我不知道在没有它的情况下如何生活。

评论


这是我曾经使用过的最伟大的软件之一。说真的我让它运行在我从任何地方都可以插入的BSD盒中,并且可以简单地重新连接到我的屏幕,并使我的所有终端都在做各种事情。

–亚当·贾斯基维奇(Adam Jaskiewicz)
08年11月12日在20:02

我可以证明这一点。屏幕是一个很好的应用程序。重新连接的能力非常出色,并节省了大量可能丢失的工作。

–willasaywhat
08年11月12日在21:06

取决于您是否需要重新连接到后台应用程序。如果这样做,那么屏幕是唯一的飞行方法。但是,如果这是一劳永逸的话,那么nohup甚至可以更好地满足要求。

–戴夫·谢罗曼(Dave Sherohman)
08年11月13日在0:36

屏幕+1。或者,作为替代,tmux(我比屏幕更喜欢这个)甚至byobu,这是屏幕或tmux的不错的前端。您可以键入screen以获取要使用的Shell,并在以后随时返回,也可以使用screen运行命令,例如“ screen command”:只要进程“ command”存在,screen会话就会存在很长一段时间,您可以随时返回并查看其标准输出。

– Gerlos
2014-2-27在19:07



Linode网站很好地介绍了如何使用屏幕。

– mabalenk
17 Mar 3 '17 at 16:03

#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.


评论


这样做的好处是可以取消已经启动的流程。

–克里斯蒂安·K。
2012年7月18日在22:49

'jobspec'是指pid吗?

– Stewart
13年6月27日在13:03

不用担心,在这里找到此答案stackoverflow.com/questions/625409/…

– Stewart
13年6月27日在13:04

#4 楼

守护吗?不行吗屏幕? (tmux ftw,屏幕很脏;-)

自从开始就做其他应用程序都做了-双叉。

# ((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[] -> 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


然后您就可以生成任何东西。 <(:)通过进程替换打开一个匿名管道,该管道将终止,但该管道会粘住,因为您拥有它的句柄。我通常会使用sleep 1而不是:,因为它有点不合时宜,并且会出现“文件繁忙”错误-如果运行了真正的命令(例如command true),则永远不会发生。 “ ::

# ./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


,它适用于我尝试过的每个外壳,包括busybox / etc(initramfs)。我以前从未见过它,我在探查时独立地发现了它,谁知道源代码可以接受args?但是,如果存在这种情况,它通常可以作为一种更易于管理的评估形式。

评论


为何要投反对票...那么,如果问题仍然存在,该怎么办?考虑到还有11个其他答案很显然是有意义的。在没有系统的情况下,此解决方案是惯用的,公认的方式来进行守护进程,而不是毫无意义的应用程序。 Nohup等。

–anthonyrisinger
2012年3月10日20:56

无论您的回答有多好,有时SO上的某个人都会不喜欢它,并且会投下反对票。最好不要太担心它。

– Alex D
2013年1月17日14:06

@ tbc0 ...尝试ssh myhost“(((exec sleep 500)&)> / dev / null”

–anthonyrisinger
13-10-8在18:45



@anthonyrisinger好的,可以。我认为这更干净:ssh myhost'sleep 500>&-2>&-<&-&'TMTOWTDI;)

–tbc0
13-10-11在6:09



这很棒。真正在busybox中有效的唯一解决方案。它值得更多投票

–汉米
16 Dec 19'在13:18

#5 楼

nohup blah &


用您的进程名称代替!

评论


您可能要添加重定向标准输出和标准错误。

– David Nehme
08年11月12日19:34

nohup将stdout和stderr重定向到nohup.out(或nohup.out和nohup.err,取决于版本),因此除非您运行多个命令,否则没有必要。

– Chas。欧文斯
09年4月21日在14:51

#6 楼

就我个人而言,我喜欢'batch'命令。

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


这会将其填充到后台,然后将结果邮寄给您。这是cron的一部分。

#7 楼

正如其他人指出的那样,要在后台运行进程以便断开与SSH会话的连接,您需要让后台进程正确地将其自身与其控制终端解除关联-这是SSH会话使用的伪tty。 br />
您可以在诸如Stevens的“ Advanced Network Program,Vol 1,3rd Edn”或Rochkind的“ Advanced Unix Programming”等书中找到有关守护进程的信息。

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

GNU getopt()函数;在Linux等系统上是有必要的(或者您必须在环境中指定POSIXLY_CORRECT)。由于双破折号在任何地方都可以使用,因此最好使用它。 gmail dot com)是否需要daemonize的源代码。
程序包
子目录。

评论


为什么不将源代码放在github或bitbucket上?

–Rob
09年9月14日在8:55

为什么缺少github上的源代码会导致失败?

–乔纳森·莱弗勒(Jonathan Leffler)
09年9月14日在9:06

@JonathanLeffler恕我直言,列出了该程序的所有很酷的选择,这些程序没有以任何形式(甚至不是商业形式)公开提供,浪费了读者的时间。

–沮丧Daniel
17年2月20日在7:28

#8 楼

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

sudo apt-get install tmux

用法:

tmux
运行所需的命令

重命名会话:

设置名称

退出会话:

Ctrl + B,然后按D

(离开tmux会话)。然后,您可以注销SSH。
当您需要再次访问/检查它时,请启动SSH,然后输入

tmux attach session_name

它将带您回到tmux会话。

评论


这是要走的路

– Kilgoretrout
18-10-25在5:15

#9 楼

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

# ((mycommand &)&)


例如:
然后启动一个新的终端窗口,然后:

# ((sleep 30 &)&)
# exit


将显示sleep 30仍在运行。

您所做的是以孩子的孩子的身份开始该进程,然后退出时,通常会触发该进程退出的nohup命令不会级联给孙子,而将其作为孤立进程继续运行。

我更喜欢这种“设置并忘记它”的方法,无需处理nohupscreen,tmux,I / O重定向或任何其他东西。

#10 楼

如果使用屏幕以超级用户身份运行进程,请注意可能会发生特权提升攻击。如果您自己的帐户因某种原因受到侵害,将有一种直接的方法来接管整个服务器。是使用cron运行作业。您还可以使用init.d(超级守护程序)在后台启动您的进程,它可以在完成后立即终止。

#11 楼

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

创建下一个屏幕
ctrl + a + c

要移至创建的下一个屏幕
ctrl + a + n

分离
/> ctrl + a + d

在工作期间关闭油灰。下次当您通过腻子登录时,请输入
screen -r
以重新连接到屏幕,然后您可以看到进程仍在屏幕上运行。并退出屏幕,键入#exit。
有关更多详细信息,请参阅man screen

评论


如果您不知道发行版,那么假设yum是正确的工具是不好的。您应该明确说明yum可以在哪个发行版屏幕上安装。

–tymik
16年5月26日在18:01

#12 楼

如果注销父进程,则Nohup允许在父进程被杀死时不杀死客户机进程。更好的方法是使用:

qq12020qq

Nohup使您的进程开始免疫终止,而SSH会话及其子进程在注销后将被终止。我提供的命令为您提供了一种将应用程序的pid存储在pid文件中的方法,以便您以后可以正确地将其杀死,并允许该过程在注销后运行。

#13 楼

使用画面。它非常易于使用,并且类似于vnc用于终端。
http://www.bangmoney.org/presentations/screen.html

#14 楼

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

#15 楼

我也想去屏幕程序(我知道其他人回答是屏幕,但这是一个完成)

不仅&&ctrl + z bg不存在,nohup等可能会给你一个事实。一个令人讨厌的惊喜,那就是当您注销工作时仍然会被杀死(我不知道为什么,但这确实发生在我身上,而且也没有打扰到我切换到使用屏幕的原因,但是我猜想anthonyrisinger解决方案可以解决两次分叉问题),而且相比于背景而言,屏幕还有一个主要优势: ..我从在任何unix中做任何事情开始就使用屏幕...我(几乎)从来没有在unix / linux shell中工作而不先启动屏幕...我现在应该停止,否则我将开始无休止的演示好的屏幕是什么以及对您有什么用呢...自己查一下,是值得的;)

评论


PS anthonyrisinger,你很好,我给你,但是... 30年?我敢打赌,当&,bg,nohup或screen还不存在时,这是一种解决方案,也没有冒犯之处,我感谢您的知识,但是使用起来太复杂了:)

–THESorcerer
2012年5月30日9:25



(旁听:请参阅Tmux)虽然这早于我[1987],但Thompson Shell在1971年为UNIX的第一个版本引入了&(异步执行)……所以它的字面意思是“一直”; ,我太保守了-实际上已经有41年了。

–anthonyrisinger
2012年9月24日4:08



#16 楼

还有开源libslack软件包的守护程序命令。

#17 楼

将此字符串附加到您的命令:>&-2>&-<&-&。 >&-表示关闭标准输出。 2>&-表示关闭stderr。 <&-表示关闭标准输入。 &表示在后台运行。这也可以通过ssh以编程方式启动作业:

$ ssh myhost 'sleep 30 >&- 2>&- <&- &'
# ssh returns right away, and your sleep job is running remotely
$


#18 楼

我使用了屏幕命令。此链接详细说明了如何执行此操作

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

#19 楼

接受的答案建议使用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\n");
    sleep (100);
    printf("Hello World\n");

    return 0;
}


编译以上代码

gcc -o hello hello.c  


并在后台使用np2运行

pm2 start ./hello


评论


可以用来运行二进制可执行文件吗?

– GetFree
17年2月6日在10:37

@免费;是。您可以。

–架子
17-2-6在10:57



请添加示例。现在的答案似乎只对脚本文件有用。

– GetFree
17年2月6日在11:12

@免费;添加了示例。如果您有任何问题,请告诉我。

–骇客
17年2月6日在11:30

#20 楼

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