我正在通过SSH(Putty)在linux机器上工作。 我需要让一个进程在夜间运行,所以我想我可以通过在后台启动进程(在命令末尾有一个&符号)并将stdout重定向到文件来做到这一点。 令我惊讶的是,这不起作用。一旦我关闭Putty窗口,该过程就会停止。
如何防止这种情况发生?
答案 0 :(得分:294)
查看“nohup”计划。
答案 1 :(得分:163)
我建议使用GNU Screen。它允许您在所有进程继续运行时断开与服务器的连接。在我知道它存在之前,我不知道我是如何在没有它的情况下生活的。
答案 2 :(得分:78)
当会话关闭时,进程收到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.
答案 3 :(得分:37)
守护进程? nohup的?屏幕? (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[$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
然后你去,产生什么。 &lt;(:)通过进程替换打开一个匿名管道,它会消失,但管道会因为你有一个句柄而四处乱窜。我通常使用sleep 1
代替:
,因为它略显活泼,而且我会收到“文件繁忙”错误 - 如果运行了真正的命令,则永远不会发生(例如command true
)
“heredoc sourcing”:
. /dev/stdin <<EOF
[...]
EOF
这适用于我曾尝试过的每一个shell,包括busybox / etc(initramfs)。我以前从未见过它,我在刺激时独立发现它,谁知道源可以接受args?但是,如果存在这样的事情,它通常可以作为一种更易于管理的评估形式。
答案 4 :(得分:33)
nohup blah &
将您的流程名称替换为blah!
答案 5 :(得分:17)
就个人而言,我喜欢'batch'命令。
$ batch
> mycommand -x arg1 -y arg2 -z arg3
> ^D
将其填入后台,然后将结果邮寄给您。这是cron的一部分。
答案 6 :(得分:11)
正如其他人所指出的那样,要在后台运行进程以便可以断开与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)。因为双破折号在任何地方都可以使用,所以最好使用它。
如果您想要daemonize
的来源,您仍然可以与我联系(gmail dot com的名字点姓氏)。
但是,现在(终于)可以在我的SOQ(Stack。)的GitHub上使用该代码
溢出问题)存储库作为文件daemonize-1.10.tgz
packages
子目录。
答案 7 :(得分:5)
Nohup允许客户端进程在父进程被终止时被杀死,以便在您注销时进行参数处理。更好的还是使用:
nohup /bin/sh -c "echo \$\$ > $pidfile; exec $FOO_BIN $FOO_CONFIG " > /dev/null
Nohup使您开始免受终止的过程,当您退出时,您的SSH会话及其子进程将被终止。我给出的命令为您提供了一种方法,您可以将应用程序的pid存储在pid文件中,以便以后可以正确地删除它,并允许该进程在您注销后运行。
答案 8 :(得分:5)
如果您使用screen以root身份运行进程,请注意权限提升攻击的可能性。如果您自己的帐户以某种方式受到损害,将有一种直接的方式来接管整个服务器。
如果需要定期运行此过程并且您在服务器上有足够的访问权限,则更好的选择是使用cron运行该作业。你也可以使用init.d(超级守护进程)在后台启动你的进程,它可以在完成后立即终止。
答案 9 :(得分:5)
nohup
非常好。但是当它转到后台时,如果你的脚本要求,你就无法给它一个密码。我想你必须尝试screen
。它是一个可以在你的Linux发行版上使用yum安装的实用程序,例如在CentOS yum install screen
上,然后通过putty或其他软件在你的shell类型screen
中访问你的服务器。它将在putty中打开screen [0]。做你的工作。您可以在同一个putty会话中创建更多屏幕[1],屏幕[2]等。
您需要了解的基本命令:
开始画面
c 重新设置下一个屏幕
要移至您创建的 n ext屏幕
d etach
在工作期间关闭你的腻子。下次通过putty type
登录时要重新连接到屏幕,您可以在屏幕上看到您的进程仍在运行。并退出屏幕,输入#exit。
有关详细信息,请参阅man screen
。
答案 10 :(得分:5)
在基于Debian的系统上(在远程计算机上) 安装:
sudo apt-get install tmux
用法:
TMUX
运行您想要的命令
重命名会话:
Ctrl + B 然后 $
设置名称
退出会话:
Ctrl + B 然后 D
(这离开了tmux会话)。然后,您可以注销SSH。
当您需要再次返回/检查时,启动SSH,然后输入
tmux attach session_name
它会带你回到你的tmux会话。
答案 11 :(得分:5)
对于大多数进程,您可以使用这个旧的Linux命令行技巧进行伪守护:
# ((mycommand &)&)
例如:
# ((sleep 30 &)&)
# exit
然后启动一个新的终端窗口并:
# ps aux | grep sleep
将显示sleep 30
仍在运行。
你所做的是作为一个孩子的孩子开始这个过程,当你退出时,通常会触发进程退出的nohup
命令不会级联到大孩子,离开它作为一个孤儿进程,仍在运行。
我更喜欢这种“设置并忘记它”的方法,无需处理nohup
,screen
,tmux,I / O重定向或其他任何内容。
答案 12 :(得分:4)
使用屏幕。它使用起来非常简单,并且像终端的vnc一样工作。 http://www.bangmoney.org/presentations/screen.html
答案 13 :(得分:2)
如果您也愿意运行X应用程序 - 请将xpra与“screen”一起使用。
答案 14 :(得分:2)
我也会选择屏幕程序(我知道其他一些答案是屏幕,但这是完成)
不仅&amp;,ctrl + z bg disown,nohup等等这一事实可能会给你一个令人讨厌的惊喜,当你注销工作时仍会被杀死(我不知道为什么,但它确实发生在我身上,而且它没有打扰它是因为我切换到使用屏幕,但我认为anthonyrisinger解决方案,因为双重分叉会解决这个问题),屏幕有一个主要优势而不仅仅是背面接地:
screen will background your process without losing interactive control to it
和btw,这是一个我永远不会问的问题:) ...我在任何unix中做任何事情的开始使用屏幕...我(几乎)从不在unix / linux shell中工作没有首先开始屏幕...我现在应该停止,或者我将开始无休止地展示什么是好的屏幕以及可以为你做什么...自己查看,这是值得的;)
答案 15 :(得分:2)
还有开源libslack软件包的daemon命令。
daemon
是可配置的,并且关心所有繁琐的守护进程,例如自动重启,日志记录或pidfile处理。
答案 16 :(得分:2)
将此字符串附加到您的命令:&gt;&amp; - 2&gt;&amp; - &lt;&amp; - &amp;。 &gt;&amp; - 表示关闭标准输出。 2&gt;&amp; - 表示关闭stderr。 &lt;&amp; - 表示关闭stdin。 &安培;意味着在后台运行。这也可以通过ssh以编程方式启动作业:
$ ssh myhost 'sleep 30 >&- 2>&- <&- &'
# ssh returns right away, and your sleep job is running remotely
$
答案 17 :(得分:1)
我使用了screen命令。此链接详细说明了如何执行此操作
https://www.rackaid.com/blog/linux-screen-tutorial-and-how-to/#starting
答案 18 :(得分:1)
接受的答案建议使用 nohup 。我宁愿建议使用pm2。在 nohup 上使用 pm2 有许多优点,例如保持应用程序处于活动状态,维护应用程序的日志文件以及更多其他功能。有关详细信息check this out。
要安装 pm2 ,您需要下载 npm 。对于基于Debian的系统
sudo apt-get install npm
和Redhat
sudo yum install npm
或者您可以关注these instruction。 安装 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".
(请参阅attributes section)。
#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
答案 19 :(得分:1)
在systemd / Linux上,systemd-run是启动与会话无关的进程的好工具。仇恨者会讨厌