Linux进程管理命令nohup、&、jobs、fg、bg、ps、kill

对Linux进程的管理是我们经常遇到的,如何查看一个进程的状态?如何把一个后台的进程调至进程执行?如何杀死一个进程…看了本文后,你将会全部掌握!

1. nohup

nohup的用法:

  • 用途:不挂断地运行命令。
  • 语法:nohup Command [ Arg … ] [ & ]
    • 在默认情况下(非重定向时),会输出一个名叫 nohup.out 的文件到当前目录下。
    • 如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out$HOME为用户主目录)文件中。
    • 如果没有文件能创建或打开以用于追加,那么 Command 参数指定的命令不可调用。
  • 参数说明:
    • Command:要执行的命令。
    • Arg:一些参数,可以指定输出文件。
    • &:让命令在后台执行,终端退出后命令仍旧执行。

现在,来尝试一下!

创建my.sh文件,文件内容如下:

1
2
3
4
5
#!/bin/bash
echo "hello"
echo "----------"
sleep 20 #休眠20s
echo "world"

执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@layne bashdir]# chmod +x my.sh  # 给my.sh增加执行权限
[root@layne bashdir]# nohup ./my.sh &
[1] 2064 #这个2064就是my.sh进程的id
[root@layne bashdir]# nohup: ignoring input and appending output to `nohup.out' #看到这个信息说明运行成功,再按一下回车即可回到当前shell命令行

[root@layne bashdir]# cat nohup.out
hello
----------
[root@layne bashdir]# cat nohup.out #等待20s再次查看
hello
----------
world
[1]+ Done nohup ./my.sh

以下命令在后台执行 my.sh 脚本,并重定向输入到 my.log 文件:

1
nohup ./my.sh > my.log 2>&1 &

解释**2>&1** :将标准错误 2 重定向到标准输出 &1 ,标准输出 &1 再被重定向输入到 my.log 文件中。这样无论正确的输出,还是错误的输出都将重定向到my.log文件中。

2. &

&用在一个命令的最后,可以把这个命令放到后台执行,可以输入jobs 查看后台执行的命令。如下所示:

1
2
3
4
[root@layne bashdir]# sleep 30 & #休眠30s,并放在后台执行
[1] 2156
[root@layne bashdir]# jobs # 查看后台的进程
[1]+ Running sleep 30 &

3. jobs

jobs命令用于查看正在执行的后台进程,但只能看当前终端生效的进程,如果关闭当前终端后,在另一个终端下,jobs已经无法看到后台跑得程序了,此时利用ps(进程查看命令)。

jobs的选项如下:

1
2
3
4
5
-l:显示进程号;
-p:仅任务对应的显示进程号;
-n:显示任务状态的变化;
-r:仅输出运行状态(running)的任务;
-s:仅输出停止状态(stoped)的任务。

jobs命令一般和-l搭配使用,可以显示后台执行进程的进程号。

这里介绍一些常见的快捷键和进程命令:

  • ctrl+c 停止当前正在执行的进程,相当于直接kill掉。
  • ctrl+z 将当前正在执行的进程放到后台,并且暂停执行,此时进程处于stop状态。
  • fg 将后台中的进程调至前台继续运行。如果后台中有多个命令,可以用fg %jobnumbe将选中的命令调出,%jobnumber是通过jobs命令查到的后台任务的编号,不是进程的pid号。
  • bg 将一个在后台暂停的命令,变成继续执行。如果后台中有多个命令,可以用bg %jobnumber将选中的命令调出。

我们首先看看jobs -l输出的信息:

1
2
3
4
5
[root@layne bashdir]# sleep 30 &
[2] 2157
[1] Done sleep 30
[root@layne bashdir]# jobs -l
[2]+ 2157 Running sleep 30 &

上面jobs -l输出4列信息,第一列表示任务编号(jobnumber),第二列表示任务所对应的进程号(pid),第三列表示任务的运行状态,第四列表示启动任务的命令。

现在,我们多启动几个后台进程,让它们处于不同的状态,并用fgbg命令调用它们到前台执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@layne bashdir]# sleep 60  #执行后,按下ctrl+z将该进程放置后台,并暂定执行
^Z
[1]+ Stopped sleep 60
[root@layne bashdir]# sleep 40 & # 让该进程放到后台执行
[2] 2159
[root@layne bashdir]# nohup ./my.sh &
[3] 2160
[root@layne bashdir]# nohup: ignoring input and appending output to `nohup.out'

[root@layne bashdir]# jobs -l
[1]+ 2158 Stopped sleep 60
[2] 2159 Running sleep 40 &
[3]- 2160 Running nohup ./my.sh &
[root@layne bashdir]# fg # 等待60s,可以看到另外两个进程也执行完了,如果这里使用fg 2,则将任务号为2的进程调至前台执行
sleep 60
[2] Done sleep 40
[3]- Done nohup ./my.sh

从上述执行过程会发现,输入jobs -l后,任务号(jobnumber)后面有 +- 两个标志,其中,+ 代表我们输入fg或bg的时候,将该进程调至前台执行。当我们把带有+的进程调至前台执行后,-标志的进程就自动变成+了,下次我们再执行fg或bg,就会调用-变为+的那个进程了。

这里不用纠结 fgbg 的区别,fg是将后台中的进程调至前台继续运行,bg将一个在后台暂停的命令变成继续执行。我在使用过程中,并没有很在意,不过用的最多的还是fg命令。

4. ps

ps命令用于查看当前系统运行的进程信息。

常用选项:

  • a : 显示所有程序
  • x :显示所有程序,不区分终端机
  • u :以用户为主的格式来显示
  • -f 显示程序间的关系
  • -e 显示所有程序

常用组合 :

ps aux 观察系统所有的进程数据

ps -ef 显示所有进程基本信息(比aux较简略一些)

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@layne bashdir]# nohup ./my.sh &
[1] 2179
[root@layne bashdir]# nohup: ignoring input and appending output to `nohup.out'

[root@layne bashdir]# ps aux | grep my.sh # 查看包含my.sh进程的信息
root 2179 0.0 0.1 106072 1332 pts/0 S 21:06 0:00 /bin/bash ./my.sh
root 2184 0.0 0.0 103256 872 pts/0 S+ 21:07 0:00 grep my.sh
[root@layne bashdir]# ps aux | head -5 # 查看当前系统所有正在执行进程的前5条
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 19232 1424 ? Ss 10:08 0:01 /sbin/init
root 2 0.0 0.0 0 0 ? S 10:08 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S 10:08 0:00 [migration/0]
root 4 0.0 0.0 0 0 ? S 10:08 0:00 [ksoftirqd/0]

上述输出的含义:

  • USER:该 process 所属的使用者。
  • PID :该 process 的进程标识符。
  • %CPU:该 process 使用掉的 CPU 资源百分比。
  • %MEM:该 process 所占用的物理内存百分比。
  • VSZ :该 process 使用掉的虚拟内存量 (Kbytes) 。
  • RSS :该 process 占用的物理的内存量 (Kbytes) 。
  • TTY :该 process 是在哪个终端机上面运作,若与终端机无关则显示 ?。另外,tty1-tty6 是本机上面的登入者程序,若为 pts/0 等,则表示为由网络连接进主机的程序
  • STAT:该进程目前的状态,状态显示与ps -l的 S 旗标相同 (R/S/D/T/Z)
  • START:该 process 被触发启动的时间
  • TIME :该 process 实际使用 CPU 运作的时间。
  • COMMAND:该程序的实际命令

5. kill

kill命令用于杀死进程,主要有两个选项:

  • kill -9 pid (见人就杀,不做善后工作)
  • kill -15 pid (调用destory等方法善后)

优先使用 -15选项,因为-15温柔一些,会做一些善后的处理(比如释放所占用的资源),如果使用-15无法杀死进程,再用-9 选项

一般情况下,先用ps命令查找要杀死进程的pid,再用kill命令杀死进程,例如:

1
2
3
4
5
6
7
[root@layne bashdir]# sleep 30 &
[1] 2194
[root@layne bashdir]# ps -aux | grep sleep
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
root 2194 0.0 0.0 100916 620 pts/0 S 21:16 0:00 sleep 30
root 2196 0.0 0.0 103256 864 pts/0 S+ 21:16 0:00 grep sleep
[root@layne bashdir]# kill -15 2194

【参考文档】
https://ipcmen.com/jobs
https://www.runoob.com/linux/linux-comm-nohup.html
https://www.linuxprobe.com/linux-nohup.html
https://blog.csdn.net/u011630575/article/details/48288663