我正在 Linux 服务器上运行一个程序,需要几天时间才能完成。
我从我的工作站的 SSH 终端启动它,因为该程序仅仅是命令行。
我希望能够做到以下所有事情:
- 启动该程序,
- 将标准输出重定向到文件,
- 退出我的 SSH 会话但不终止该进程。
我想过$ ./MyProg.csh -params -foo -bar </dev/null 1>~/out.log 2>~/err.log &
但是,当我关闭 SSH 会话时,该过程就会终止。我的工作站运行的是 Windows XP,我无法保证它能正常运行几天,而这是在 Linux 服务器上处理我的数据所必需的。
您可能已经注意到,我的程序需要从 CSH 启动。
是否有可能做到这一点 ?
谢谢。
答案1
您可以使用screen
或nohup
如果你选择screen
:
screen
在运行服务之前启动:
$ screen
然后,在里面运行你的服务screen
:
./MyProg.sh > myprog.log
(或任何您想要的东西)。
然后Ctrl+a d
当你回来时,只需:
$ screen -r
了解更多信息:http://www.gnu.org/s/screen/
关于 nohup :只是:
nohup ./MyProg.sh > myprog.log &
答案2
制作一个像这样的外壳包装器:
#!/bin/sh
exec </dev/null
exec >> ~/out.log
exec 2>> ~/err.log
exec setsid ./MyProg.csh -params -foo -bar
如果您也需要 PID 文件,请将此 shell 脚本发送到 bg 并读取 $!(最后一个 bg 进程的 PID)。您可以在同一个脚本中使用带有 () 的子 shell 执行此操作,如下所示:
#!/bin/sh
( exec </dev/null
exec >> ~/out.log
exec 2>> ~/err.log
exec setsid ./MyProg.csh -params -foo -bar
) &
kill -0 $! > /dev/null 2>&1 || exit 1
echo $! > program.pid
exit 0
答案3
连接断开是因为 shell 在退出时会向所有子进程发送 SIGHUP。如果您使用 bash 或 zsh,则可以使用disown
,这样 shell 将不再发送 SIGHUP,进程将保留。
screen
及setsid
以上方法均可行,但此答案的优点在于,在开始任何操作之前无需记住执行屏幕操作。 screen
除此之外,它还有很多其他功能,因此您可能想要养成使用它的习惯。