当我们 ssh 登录上 Linux shell 之后,在此终端下可以同时执行多个命令或脚本,对这些任务的管理就叫做工作管理。比如:想要一边复制文件,一边进行数据查找。
job control 进行管理的进程必须是你 shell 的子进程。
01
—
&
& 可以直接将命令丢到后台中运行,比如我们要将 etc/ 整个备份成为 tmp/etc.tar.gz 且不想要等待,那么可以这样做:
meng➜/tmp» tar -zpcf tmp/home.tar.gz home/meng & [21:03:46][1] 28270
[1]:是 job number
28270:进程 PID
在后台当中运行的命令,如果有 stdout 及 stderr 时,它的数据依旧是输出到屏幕上面的。所以,最佳的状况就是利用数据流重定向, 将输出数据传送至某个文件中。
tar -zpcf tmp/home.tar.gz home/meng > /tmp/log.txt 2>&1 &
02
—
job 管理
jobs:列出当前 shell 中执行的 job
meng➜/tmp» jobs [21:03:52][1] + running tar -zpcf tmp/home.tar.gz home/meng
选项与参数:
fg:将后台工作拿到前景来处理
fg %job_number
比如上面我们通过 & 将打包命令放在了后台执行,通过 jobs 拿到 job number 1,然后通过 fg %1 即可拿到前台来处理。
bg:让工作在后台下的状态变成运行中
比如上面打包命令,忘记加 & 放后台执行了,这个时候要放到后台执行怎么办呢?
按键 Ctrl + z 将当前工作丢到后台暂停,然后再通过 bg %job_number ,将工作运行。
meng➜/tmp» sh ./task.sh [21:24:51]^Z[1] + 28429 suspended sh ./task.shmeng➜/tmp» jobs [21:24:55][1] + suspended sh ./task.shmeng➜/tmp» bg %1 [21:25:00][1] + 28429 continued sh ./task.sh
kill:管理后台当中的工作
meng➜/tmp» kill %1 [21:25:06][1] + 28429 terminated sh ./task.sh
03
—
脱机管理
上面我们讲的命令执行都是在当前 shell 中执行,如果退出 shell 命令都会被关闭掉。你在 shell 中执行的命令,这些命令的父进程都是 shell 进程,当你退出 shell 的时候系统会给 jobs 列出的进程发送信号:SIGHUP,这会导致进程关闭。
通过 ps 可以看到对应进程的父进程(PPID)
meng➜/tmp» ps -ejf| head [21:41:30]UID PID PPID PGID SID C STIME TTY TIME CMDroot 1 0 1 1 0 Aug20 ? 00:00:17 sbin/init splashroot 2 0 0 0 0 Aug20 ? 00:00:00 [kthreadd]root 4 2 0 0 0 Aug20 ? 00:00:00 [kworker/0:0H]
简单讲下 PGID 和 SID
SID:Session Identifier (Session Leader)。当前 shell 进程id,可以通过环境变量输出:
echo $$
PGID:Process Group Identifier (Process Group Leader)。我一次执行多个命令就可以认为是一个 Process Group,Leader 就是取第一个命令的进程id。

nohup:让进程忽略掉 SIGHUP 信号。
如下所示,task.sh 的进程对应的父进程是当前 shell 进程。当我们退出终端,重新进入后,父进程就变成了系统的 1 号进程(退出终端后,找不到父进程,这个时候进程就会被挂在 1 号进程下)。
meng➜/tmp» nohup sh ./task.sh & [21:59:56][1] 29164meng➜/tmp» ps -lf [22:00:50]F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD0 S meng 29063 29062 0 80 0 - 13532 sigsus 21:57 pts/2 00:00:00 -zsh0 S meng 29164 29063 0 85 5 - 1157 wait 22:00 pts/2 00:00:00 sh ./task.sh# 退出终端,重新进入meng➜~» ps -ejf| grep task.shUID PID PPID PGID SID C STIME TTY TIME CMDmeng 29164 1 29164 29063 0 22:00 ? 00:00:00 sh ./task.sh
我们已经知道,如果事先在命令前加上 nohup 就可以在你关闭终端后继续运行程序。但是如果我们未加任何处理就已经提交了命令,该如何补救呢。
disown 它可以将指定任务从"后台任务"列表(jobs命令的返回结果)之中移除。一个"后台任务"只要不在这个列表之中, 关闭 shell 的时候肯定不会向它发出SIGHUP 信号。
# 移出最近一个正在执行的后台任务$ disown# 移出所有正在执行的后台任务$ disown -r# 移出所有后台任务$ disown -a# 不移出后台任务,但是让它们不会收到SIGHUP信号$ disown -h# 根据jobId,移出指定的后台任务$ disown %2$ disown -h %2
长按二维码关注,获得更多干货文章





