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

令我惊讶的是,这行不通。只要我关闭Putty窗口,进程就会停止。

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


当前回答

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

Sudo apt-get install tmux

用法:

tmux 运行您想要的命令

重命名会话:

按Ctrl+B然后$ 集名称

退出会话:

按Ctrl+B然后D

(这会留下tmux会话)。此时可以退出SSH。

当您需要再次返回/检查它时,启动SSH,并输入

Tmux附加session_name

它将带您回到tmux会话。

其他回答

我也会去屏幕程序(我知道some1其他答案是屏幕,但这是一个完成)

事实不仅是&,ctrl+z bg disown, nohup等可能会给你一个讨厌的惊喜,当你退出工作仍然会被杀死(我不知道为什么,但它确实发生在我身上,它没有打扰它,因为我切换到使用屏幕,但我猜anthonyrisinger解决方案作为双分叉将解决这个问题),屏幕也有一个主要的优势,只是背景:

screen will background your process without losing interactive control to it

顺便说一句,这是一个我一开始就不会问的问题:)…我从一开始在Unix上做任何事情就使用screen…我(几乎)从未在unix/linux shell中工作而不首先开始屏幕…我现在应该停止了,否则我将开始无休止的演示什么是好屏幕以及可以为你们做什么……自己去查吧,很值得的;)

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”程序。

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

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

这将把它塞到后台,然后将结果邮寄给你。这是cron的一部分。

当会话关闭时,进程接收到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.