我正在通过SSH (Putty)在Linux机器上工作。我需要让一个进程在夜间运行,因此我认为可以通过在后台启动该进程(在命令末尾使用&号)并将stdout重定向到一个文件来实现这一点。
令我惊讶的是,这行不通。只要我关闭Putty窗口,进程就会停止。
我怎样才能防止这种情况发生?
我正在通过SSH (Putty)在Linux机器上工作。我需要让一个进程在夜间运行,因此我认为可以通过在后台启动该进程(在命令末尾使用&号)并将stdout重定向到一个文件来实现这一点。
令我惊讶的是,这行不通。只要我关闭Putty窗口,进程就会停止。
我怎样才能防止这种情况发生?
当前回答
nohup blah &
用您的进程名替换blah!
其他回答
当会话关闭时,进程接收到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.
使用屏幕。它使用起来非常简单,就像终端的vnc一样。 http://www.bangmoney.org/presentations/screen.html
正如其他人所指出的,要在后台运行进程以便与SSH会话断开连接,您需要让后台进程正确地与它的控制终端断开关联——这是SSH会话使用的伪tty。
您可以在Stevens的“高级网络程序,第1卷,第3版”或Rochkind的“高级Unix编程”等书籍中找到有关守护进程的信息。
最近(在过去的几年里),我不得不处理一个不听话的程序,它没有正确地守护自己。最后,我创建了一个通用的daemonizing程序来解决这个问题——类似于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)。由于双破折号在任何地方都适用,所以最好使用它。
如果你想要daemon的源代码,你仍然可以联系我(firstname . lastname at gmail . com)。
然而,代码现在(终于)在GitHub上我的SOQ(堆栈)中可用 溢出问题)存储库为文件daemonize-1.10。TGZ在 包 子目录。
daemonize吗?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
这就是,衍生什么的。<(:)通过进程替换打开一个匿名管道,这将终止,但管道仍然存在,因为您拥有它的句柄。我通常用sleep 1代替:因为它有点不正常,我会得到一个“file busy”错误——如果运行一个真正的命令(例如,command true),永远不会发生。
“heredoc采购”:
. /dev/stdin <<EOF
[...]
EOF
这适用于我尝试过的每一个shell,包括busybox/etc (initramfs)。我以前从未见过这种情况,我是自己发现的,谁知道来源可以接受args呢?但它通常是一种更易于管理的计算形式,如果有的话。
如果您想将详细信息记录到一个文件中,Nohup非常有用。但当它进入后台时,如果你的脚本要求,你无法给它一个密码。我想你一定要试一下屏幕。它是一个实用工具,你可以使用yum安装在你的linux发行版上,例如在CentOS上yum安装屏幕,然后通过putty或其他软件在你的shell类型屏幕上访问你的服务器。它将打开屏幕[0]在腻子。做好你的工作。你可以在同一个putty会话中创建更多的screen[1], screen[2]等。
你需要知道的基本命令:
启动屏幕
屏幕
创建下一个屏幕
ctrl + a + c
移动到您创建的下一个屏幕
ctrl + a + n
要分离
ctrl + a + d
在工作期间关闭腻子。下次当你登录通过putty类型
屏幕- r
重新连接到屏幕,您可以看到您的进程仍在屏幕上运行。要退出屏幕,输入#exit。
欲了解更多细节,请参阅男子界面。