一、HUP信号
- 当用户注销(logout)或者网络断开或者关闭终端时(一定是终端整体关闭,而不是单纯的exit)时,终端会收到Linux HUP信号,然后终端在结束前会关闭所有子进程。
- 如果我们想让进程在后台一直运行,不要因为用户注销(logout)或者网络断开、终端关闭而一起被干掉,那么我们有两种解决方案
- 方案一:让进程忽略Linux HUP信号
- 方案二:让进程运行在新的会话里,从而成为不属于此终端的子进程,就不会在当前终端挂掉的情况下一起被带走。
nohup命令
针对方案一,我们可以使用nohup命令,nohup的用途就是让提交的命令忽略hangup信号,该命令通常与&符号一起使用
- [root@@321 ~]# nohup ping www.baidu.com & > /root/1.txt &
[3] 9948
- 查看当前终端9948的父PID
[root@@321 ~]# ps -elf | grep [p]ing
4 S root 9937 9579 0 80 0 - 37492 poll_s 21:11 pts/1 00:00:00 ping www.baidu.com
4 S root 9948 9579 0 80 0 - 37492 poll_s 21:17 pts/1 00:00:00 ping www.baidu.com
3. 关闭当前终端,在另一终端查看它的父PID(这时我们会发现后台运行的ping进程依旧在运行,并且它的父进程PID号变成了 一,即init进程)[root@@321 ~]# ps -elf | grep [p]ing
4 S root 9937 1 0 80 0 - 37492 poll_s 21:11 ? 00:00:00 ping www.baidu.com
4 S root 9948 1 0 80 0 - 37492 poll_s 21:17 ? 00:00:00 ping www.baidu.com
setsid命令
针对方案1,我们汉可以用setsid命令实现,原理与nohup是一样的,setsid直接将进程的父pid设置成1,即让运行的进程归属于init子进程,那么除非init结束,该子进程才会结束,当前进程所在的终端结束后并不会影响进程的运行。
在终端1中执行命令
- [root@@321 ~]# setsid ping www.baibu.com 也可以在后面加&符号
关闭终端1
在终端2查看
[root@@321 ~]# ps -elf | grep [p]ing
4 S root 18443 1 0 80 0 - 33160 skb_wa 17:40 ? 00:00:00 ping www.baibu.com
在子shell中提交任务
在终端1中执行命令
[root@@321 ~]# (ping www.baibu.com &)
关闭终端1
在终端2查看
[root@@321 ~]# ps -elf | grep [p]ing
root 18443 1 0 80 0 - 33160 skb_wa 17:40 ? 00:00:00 ping www.baibu.com
screen命令
安装:yum install screen -y
运行命令
开启一个窗口并用-S指定窗口名,也可以不指定
例如:[root@@321 ~]# screen -S 窗口
如果非正常退出或关门窗口后,下次在进入可用以下命令
[root@@321 ~]# screen -r
There are several suitable screens on:
8381.窗口 (Attached)
8280.lili (Detached)
screen会帮我们管理运行的命令,退出screen,我们的命令还会继续运行
若关闭screen所在的终端,则screen程序的ppid变为1,所有screen不会死掉,
对应着它帮我们管理的命令也不会退出
注意:如果我们刚开始以经用screen -S xxx指定了名字,那么我们可以直接
screen -r xxx,就不用去找程序的id了
远程演示
在终端1
[root@@321 ~]# screen -S 远程连接
在终端2
[root@@321 ~]# screen -x 远程连接
右边的终端输入内容会同步到左边终端
jobs:查看在当前终端提交的后台进程(前提是必须连接到一台服务器上)
查看网络状态
netstat
[root@@321 ~]# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 6350/rpcbind
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 6945/sshd
-t :tcp协议-u :udp协议
-l :listen 监听状态
-n :不反解,不将IP地址解析为主机名,不将端口解析成协议名(80---》http)
proc文件系统
[root@@321 ~]# du -sh /root
100M /root
内存:/proc/meminfo
#释放内存举例
[root@@321 ~]# free
total used free shared buff/cache available
Mem: 995896 97424 632300 7808 266172 727160
Swap: 2097148 0 2097148
[root@@321 ~]# sync
[root@@321 ~]# echo 3>/proc/sys/vm/drop_caches
内核启动参数:/proc/cmdline
root@@321 ~]# cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-3.10.0-957.el7.x86_64 root=/dev/mapper/centos-root ro rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet LANG=zh_CN.UTF-8[root@@321 ~]# uptime
00:04:52 up 15:24, 1 user, load average: 0.00, 0.01, 0.05
注意:当我们卸载/proc后
[root@@321 ~]# umount /proc -l
#下述命令都不可以
free -m
uptime
lscpu
toop
#重新挂载
[root@@321 ~]# mount -t proc proc /proc/
-t proc 指定文件系统类型
proc 文件系统,虚拟文件系统
/proc 挂载点
管理后台进程
[root@@321 ~]# sleep 300 & #程序运行时,让其在后台执行
[1] 14378
[root@@321 ~]# sleep 300 &
[2] 14427
[root@@321 ~]# jobs #中括号内编号就是当前作用编号,%1代表作用1
[1]- 运行中 sleep 300 &
[2]+ 运行中 sleep 300 &
[root@@321 ~]# bg %2 #让作业2在后台运行
-bash: bg: 任务 2 已在后台
[root@@321 ~]# fg %1 #将作业一调回前台
sleep 300
管道
什么是管道?
管道用于进程之间通信,详细的说,管道操作符号“|”,主要用来连接左右两个命令,将左侧命令的标准输出,交给右侧命令的标准输入
管道应用示例:
统计当前/etc/passwd中用户使用shell类型
[root@@321 ~]# awk -F: '{print $7}' /etc/passwd | sort |uniq -c
2 /bin/bash
1 /bin/sync
1 /sbin/halt
18 /sbin/nologin
1 /sbin/shutdown
xargs参数传递,主要让一些不支持管道的命令也可以使用管道技术
[root@@321 ~]# which cat | xargs ls -l
-rwxr-xr-x. 1 root root 54160 10月 31 2018 /usr/bin/cat
[root@@321 ~]# ls | xargs rm -fv
僵尸进程和孤儿进程
什么是僵尸进程 ?
僵尸进程就是子进程先于父进程运行完毕/死掉,那么Linux系统在清理子进程的时候,会将子进程占用的重型资源都释放掉(比如占用的内存空间、CPU资源、打开的文件等),但会保留一部分子进程的关键状态信息,比如进程号、退出状态、运行时间等,此时子进程就相当于死了但没死干净,因而得名“僵尸进程”。
分两种情况:
①一些水平良好的程序员开发的应用程序,会在父进程内考虑调用 wait
/waitpid来通知操作系统回收2僵尸进程,但是发起系统调用wait/waitpid
的时间可能慢了些,于是我们可以在Linux系统中查看僵尸进程状态
[root@@321 ~]# ps aux | grep [z]+
针对这种情况,可以发信号给父进程,通知它快点发起系统调用wait/waitpid
来清理僵尸的儿子 (kill -CHLD 父进程PID)
②一些初级程序员,根本不知道什么是僵尸进程,至于wait/waitpid的系统
调用更是没听说过,这个时候在开发的时候根本不会去管后台的程序运行
,以至于操作系统中的僵尸进程会堆积起来,此时我们的计算机会进入一
个奇怪的现象,就是内存充足、硬盘充足、CPU空闲,但是就是无法启动
新的进程,为啥?因为操作系统负责管理进程,每启动一个进程就分派一
个PID号,而PID号有限,会被僵尸进程占满。
针对这种情况,只有一种解决方案,就是杀死父进程,那么子进程会被Linux
系统中PID为1的顶级进程(init或systemd)接管,顶级进程会定期发起系统
调用wait /waitpid来通知操作系统清理僵尸进程。
孤儿进程
父进程先死掉,而他的一个或多个子进程还在运行,那么这些子进程将成为
孤儿进程。孤儿进程将被进程号为1的顶级进程(init或systemd)收养,并
由顶级进程对它们完成状态收集工作,所有僵尸进程在这种情况下是不存在
的存在的只有孤儿进程而已,孤儿进程生命周期结束自然会被顶级进程销毁
掉。