linux命令行将程序置入后台的各种方法

背景

在一次备份数据的过程中, 数据太大, 导致多次失败(退出终端后rsync也退出了), 后来用了screen算是解决了这个问题.
然后就想对这种问题总结下.

准备

为了演示, 我写了几个脚本模拟需要长时间运行的任务, 这些脚本会放在服务器上, 然后我ssh过去执行这些脚本.

1. 不需要交互, 长时间运行

$ cat forever.sh

#! /bin/sh

logFile=`basename $0`.log
while true; do
	echo "running at $(date)" >> $logFile
	sleep 1
done

2. 需要交互(最常见的就是输入密码)

$ cat forever-read.sh

#! /bin/sh

read -p "enter password:" pass

if [ x"$pass" != x123  ]; then
	echo "password error"
	exit 2
fi

echo "password is ok"
logFile=`basename $0`.log
while true; do
	echo "running at $(date)" >>  $logFile
	sleep 1
done

方法

&

这个众所周知, &可以将一个任务置入后台, 但是此任务是与当前终端关联的, 也就是当前终端退出后, 此任务也会退出. 演示如下:

# 在服务器上 用&的方式执行
root@server1: ~ # bash forever.sh &
[1] 73510
# exit退出
root@server1: ~ # exit
zsh: you have running jobs.
root@server1: ~ # exit
zsh: warning: 1 jobs SIGHUPed
[1]  + 73510 hangup     bash forever.sh

Connection to myvm closed.

# 再登录上去看forever.sh有没有在执行
$ ssh root@myvm
Last login: Sat Apr  4 12:55:16 2020 from 10.25.1.89

# 发现并没有被执行
root@server1: ~ # ps -ef|grep forever|grep -v grep

通过上面的实验我发现,
&这种方式将任务放入后台, 如果退出(exit)了, &执行的任务也就退出了.

nohup

nohup这个命令可以说是相当优秀了. 记忆中第一次用它的时候比较奇怪, 这玩意怎么是这样的, 卡住不动了, 啥也输入不了. 演示如下:
nohup bash forever.sh之后, 随便输入无效, 然后ctrl-C退出, 再看发现forever.sh已经不再运行.

root@server1: ~ # nohup bash forever.sh
nohup: ignoring input and appending output to ‘nohup.out’
fldskfjsdlakfjdas;fjsad;lfkjsad;lfsjad;fsda

... 一通输入没效果...
fsdafsadfjsdal

# ctrl-C
ds^C
FAIL: 130
root@server1: ~ # ps -ef|grep forever 

所以
直接使用nohup的方式, 按ctrl-C也会导致任务退出

但是我又这样做, nohup bash forever.sh之后直接把当前窗口关了(如果你用的是xshell等之类的话, 应该是关闭一个tab), 再开一个窗口登录server, 发现forever.sh还在运行.
虽然这样可以, 但是这样总感觉不优雅.

常见用法

其实我们常用的是这样的: nohup command 2>&1 &

root@server1: ~ # nohup bash forever.sh 2>&1 &
[1] 36892
nohup: ignoring input and appending output to ‘nohup.out’

这种方式确实可以满足我们的需要, 终端退出任务不退出, 而且看起来也很好.

nohup的问题

那么这种方式有没有什么问题呢?
有的, 在处理交互式的命令时(如rsync, scp等)会有问题, 如运行上面给出的forever-read.sh,
会直接退出:

root@server1: ~ # nohup bash forever-read.sh 2>&1 &
[2] 82404
nohup: ignoring input and appending output to ‘nohup.out’                                                                           
[2]  + 82404 exit 2     nohup bash forever-read.sh 2>&1
root@server1: ~ # tail -n 2 nohup.out
forever-read.sh: line 3: read: read error: 0: Bad file descriptor
password error

screen

所以对这种带有交互式的应该怎么办呢? 我最后选用了screen命令, 这个命令有很多选项, 但是实际使用的话只会几个操作就行了. 用screen来运行forever-read.sh过程如下:

# 新建立会话, -S forever-read是给会话起名字, 可选
screen -S forever-read

# 像平常一样执行交互式任务
bash forever-read.sh
enter password:123

# 输入密码后回车
password is ok

按 Ctrl-a-d(同时按下ctrl, a, d三个键), 表示暂时脱离此会话
[detached from 84547.forever-read]
 84547.forever-read是会话id, 其实用数字或者你自定义的名字或者全名都可以

# 重新回到指定会话查看任务执行情况.
screen -r 84547.forever-read

tmux

这个和screen操作类似, 我自己用过几次, 不熟练, 就不写了.

总结

  • 没有交互的用nohup最方便, 因为screen或者tmux一般也不会自带.
  • 带有交互的用screen或者tmux非常方便

欢迎补充指正!

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 黑客帝国 设计师: 上身试试
应支付0元
点击重新获取
扫码支付

支付成功即可阅读