绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
Linux job control
2021-01-22 17:05:23

当我们 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

选项与参数: -l -l :除了列出 job number 与命令串之外,同时列出 PID 的号码; -r -r :仅列出正在后台 run 的工作; -s -s :仅列出正在后台当中暂停 (stop) 的工作。

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.sh
meng➜/tmp» jobs                                                                                                                                                                                  [21:24:55]
[1]  + suspended  sh ./task.sh
meng➜/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 CMD
root         1     0     1     1  0 Aug20 ?        00:00:17 /sbin/init splash
root         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] 29164
meng➜/tmp» ps -lf                                                                                                                                                                                [22:00:50]
F S UID        PID  PPID  C PRI  NI ADDR SZ WCHAN  STIME TTY          TIME CMD
0 S meng     29063 29062  0  80   0 - 13532 sigsus 21:57 pts/2    00:00:00 -zsh
0 S meng     29164 29063  0  85   5 -  1157 wait   22:00 pts/2    00:00:00 sh ./task.sh
# 退出终端,重新进入
meng➜~» ps -ejf| grep task.sh
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
meng     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

文章作者|来源:CoderMeng



分享好友

分享这个小栈给你的朋友们,一起进步吧。

Linux技术精选专区
创建时间:2020-07-08 10:30:23
Linux,全称GNU/Linux,是一套免费使用和自由传播的类UNIX操作系统,其内核由林纳斯·本纳第克特·托瓦兹于1991年次释出,它主要受到Minix和Unix思想的启发,是一个基于POSIX和Unix的多用户、多任务、支持多线程和多CPU的操作系统。它能运行主要的Unix工具软件、应用程序和网络协议。
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

技术专家

查看更多
  • dapan
    专家
戳我,来吐槽~