Linux上远程执行命令程序,有时可能耗时比较长(传输文件或更新程序等),如果出现网络不稳定中断或客户端电脑睡眠等情况,就比较令人郁闷。这时要执行的命令程序在后台运行,这样即时断开连接,也还是会继续运行。本文主要介绍使用&、ctrl+z或screen命令来后台执行命令程序。

1、使用&后台运行命令

&:将当前命令以后台的形式运行;
ps:查看正在运行的进程信息;
kill:杀掉某个进程;

1) 使用&后台运行

&加在一个命令的最后,可以把当前行的命令放在后台执行。注意&前面有空格。当非正常退出当前shell终端时,后台运行的update.sh也会结束。因为脚本在后台运行时,运行脚本的父进程是当前shell终端进程,关闭当前shell终端时,会发送hangup挂断信号给子进程,子进程收到hangup信号后也就退出。

cjavapy@ubuntu:~$ sudo chmod 755 update.sh
cjavapy@ubuntu:~$ ./update.sh &

2) 使用nohup和&后台运行

cjavapy@ubuntu:~$ nohup ./update.sh &

命令前加上nohup可以让你退出shell之后继续运行相应的进程。nohup就是忽略当前任务挂断信号。如果不想像上面一样退出,这样就可以解决。

nohup默认会把标准输出重定向到默认文件nohup.out中,可以自定义该输出文件,如下,

cjavapy@ubuntu:~$ nohup ./update.sh >out.txt &

2、使用ctrl+z、jobs和bg后台运行

ctrl+z:将前台任务转后台并冻结;
bg:将后台冻结的任务再次运行起来;
fg:将后台任务重新转前台执行;
jobs:查看在后台运行的任务列表;

ctrl+z命令可以将当前的前台任务转后台,放到后台任务池中,前台窗口就变成非阻塞状态了,但转过去的任务在后台默认是冻结状态。这时需要用到bg命令,bg命令的功能就是将后台冻结的任务再次运行起来,但它需要一个任务ID号,而jobs命令就是查看所有任务状态的,包括ID号。

cjavapy@ubuntu:~$ ./update.sh
[4]+ 已停止 ./update.sh
cjavapy@ubuntu:~$ jobs
[4]+ 已停止 ./update.sh
cjavapy@ubuntu:~$ bg 4
[4]+ ./update.sh &
[4]+ 已完成 ./update.sh
cjavapy@ubuntu:~$

3、使用Screen后台执行

$> screen [-AmRvx -ls -wipe][-d <作业名称>][-h <行数>][-r <作业名称>][-s ][-S <作业名称>]
-A  将所有的视窗都调整为目前终端机的大小。
-d <作业名称>  将指定的screen作业离线。
-h <行数>  指定视窗的缓冲区行数。
-m  即使目前已在作业中的screen作业,仍强制建立新的screen作业。
-r <作业名称>  恢复离线的screen作业。
-R  先试图恢复离线的作业。若找不到离线的作业,即建立新的screen作业。
-s  指定建立新视窗时,所要执行的shell。
-S <作业名称>  指定screen作业的名称。
-v  显示版本信息。
-x  恢复之前离线的screen作业。
-ls或--list  显示目前所有的screen作业。
-wipe  检查目前所有的screen作业,并删除已经无法使用的screen作业。

1) 常用screen参数

screen -S yourname -> 新建一个叫yourname的session
screen -ls -> 列出当前所有的session
screen -r yourname -> 回到yourname这个session
screen -d yourname -> 远程detach某个session
screen -d -r yourname -> 结束当前session并回到yourname这个session

2) 在screen中Session常用快捷键

ctrl+a d ->detach,暂时离开当前session,将目前的 screen session (可能含有多个 windows) 丢到后台执行,并会回到还没进 screen 时的状态,此时在 screen session 里,每个 window 内运行的 process (无论是前台/后台)都在继续执行,即使 logout 也不影响。 
ctrl+a z -> 把当前session放到后台执行,用 shell 的 fg 命令则可回去。
ctrl+a w -> 显示所有窗口列表
ctrl+a k -> kill window,强行关闭当前的 window
ctrl+a [ -> 进入 copy mode,在 copy mode 下可以回滚、搜索、复制就像用使用 vi 一样
C-b Backward,PageUp
C-f Forward,PageDown
H(大写) High,将光标移至左上角
L Low,将光标移至左下角
0 移到行首
$ 行末
w forward one word,以字为单位往前移
b backward one word,以字为单位往后移
Space 第一次按为标记区起点,第二次按为终点
Esc 结束 copy mode
ctrl+a ] -> paste,把刚刚在 copy mode 选定的内容贴上

3) 常用操作

创建会话(-m 强制):screen -dmS session_name
关闭会话:screen -X -S [session # you want to kill] quit
查看所有会话:screen -ls
进入会话:screen -r session_name

4、查看后台任务命令

1) jobs查看当前终端任务信息

cjavapy@ubuntu:~$ jobs -l
[1]- 3427 运行中 nohup ./update.sh &
[2]+ 3445 运行中 nohup python &

jobs -l选项可以多显示一个PID信息。

第一列:任务序号,注意并不是PID。
第二列:+ 号表示当前顶部任务,- 号其次任务,没符号是其他任务。
第三列:PID(上面例子中,默认情况下没有PID)。
第四列:状态,四种(运行中,已停止,已完成,已杀死)。
第五列:任务名称(即刚才运行的命令)。

2) ps全局查看进程信息

cjavapy@ubuntu:~$ ps -ef |grep gedit
root 3591 2566 0 00:29 pts/0 00:00:00 sudo gedit
root 3592 3791 0 00:29 pts/0 00:00:00 gedit
cjavapy 3321 2566 0 00:44 pts/0 00:00:00 grep --color=auto gedit

第一列:用户名
第二列:PID
第三列:父级PID
最后一列:命令名称或路径

ps -ef

e:表示列出所有进程,f:表示输出完整格式。

5、关闭后台任务命令

任务运行完毕会自行退出;通过交互方式退出(包括传入参数对话,界面操作,终端ctrl+c等);通过进程管理工具杀掉;

kill命令:属于进程管理工具,可以杀掉进程。

1) 使用任务号kill进程

cjavapy@ubuntu:~$ jobs
[2] 已停止 nohup firefox
[3]- 已停止 nohup sudo gedit
cjavapy@ubuntu:~$ kill -9 %2
[2] 已停止 nohup firefox
cjavapy@ubuntu:~$ jobs
[2] 已杀死 nohup firefox
[3]- 已停止 nohup sudo gedit

2) 通过PID来kill进程

cjavapy@ubuntu:~$ ps -ef |grep gedit
root 3731 2566 0 20:23 pts/0 00:00:00 sudo gedit
root 3732 3791 0 20:29 pts/0 00:00:00 gedit
cjavapy 3429 2566 0 20:59 pts/0 00:00:00 grep --color=auto gedit
cjavapy@ubuntu:~$ sudo kill -9 3731
[sudo] cjavapy 的密码:
[3]- 已杀死 nohup sudo gedit

相关文档:

linux 在指定目录下的所有文件中查找text文本的方法
Linux Vim(vi) 常使用命令快捷键合集
Linux 文件压缩和归档命令(command)总结
Linux 命令(command) history