内核功用:进程管理、内存管理、文件系统、网络功能、驱动程序、安全功能等
什么是程序?
程序是执行特定任务的一串代码
其是静态资源(硬盘上 躺着)
什么是进程?
其是动态资源,加载到内存中运行
运行中的程序的一个副本,是被载入内存的一个指令集合,是资源分配的单位,
进程ID(Process ID,PID)号码被用来标记各个进程
UID、GID语境决定对文件系统的存取和访问权限
通常从执行进程的用户来继承
存在生命周期
都由其父进程创建
进程创建:
CentOS第一个进程:init, CentOS7 第一个进程:systemd
进程:都由其父进程创建,fork(),父子关系,CoW:Copy On Write 写实更新,有数据写入子进程需要新的内存空间
动态性:进程是程序的一次执行过程,是临时的,有生命期的,是动态产生,动态消亡的;
并发性:任何进程都可以同其他进程一起并发执行;
独立性:进程是系统进行资源分配和调度的一个独立单位;
结构性:进程由程序、数据和进程控制块三部分组成。
进程
进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度
的一个独立单位,是应用程序运行的载体。进程是一种抽象的概念,从来没有统一的标准定义。
进程的组成
进程一般由程序、数据集合和进程控制块三部分组成。
程序用于描述进程要完成的功能,是控制进程执行的指令集;
数据集合是程序在执行时所需要的数据和工作区;
程序控制块(Program Control Block,简称PCB),包含进程的描述信息和控制信息,是进程存在的唯一
标志。
进程具有的特征:
动态性:进程是程序的一次执行过程,是临时的,有生命期的,是动态产生,动态消亡的;
并发性:任何进程都可以同其他进程一起并发执行;
独立性:进程是系统进行资源分配和调度的一个独立单位;
结构性:进程由程序、数据和进程控制块三部分组成。
线程
在早期的操作系统中并没有线程的概念,进程是能拥有资源和独立运行的最小单位,也是程序执行的最小单
位。任务调度采用的是时间片轮转的抢占式调度方式,而进程是任务调度的最小单位,每个进程有各自独立的
一块内存,使得各个进程之间内存地址相互隔离。
后来,随着计算机的发展,对CPU的要求越来越高,进程之间的切换开销较大,已经无法满足越来越复杂的程
序的要求了。于是就发明了线程。
线程是程序执行中一个单一的顺序控制流程,是程序执行流的最小单元,是处理器调度和分派的基本单位。一
个进程可以有一个或多个线程,各个线程之间共享程序的内存空间(也就是所在进程的内存空间)。一个标准的
线程由线程ID、当前指令指针(PC)、寄存器和堆栈组成。而进程由内存空间(代码、数据、进程空间、打开的
文件)和一个或多个线程组成。
协程
协程,英文Coroutines,是一种基于线程之上,但又比线程更加轻量级的存在,这种由程序员自己写程序来
管理的轻量级线程叫做『用户空间线程』,具有对内核来说不可见的特性。
因为是自主开辟的异步任务,所以很多人也更喜欢叫它们纤程(Fiber),或者绿色线程
(GreenThread)。正如一个进程可以拥有多个线程一样,一个线程也可以拥有多个协程。
协程的目的
在传统的J2EE系统中都是基于每个请求占用一个线程去完成完整的业务逻辑(包括事务)。所以系统的吞吐能
力取决于每个线程的操作耗时。如果遇到很耗时的I/O行为,则整个系统的吞吐立刻下降,因为这个时候线程
一直处于阻塞状态,如果线程很多的时候,会存在很多线程处于空闲状态(等待该线程执行完才能执行),造
成了资源应用不彻底。
最常见的例子就是JDBC(它是同步阻塞的),这也是为什么很多人都说数据库是瓶颈的原因。这里的耗时其实
是让CPU一直在等待I/O返回,说白了线程根本没有利用CPU去做运算,而是处于空转状态。而另外过多的线
程,也会带来更多的ContextSwitch开销。
对于上述问题,现阶段行业里的比较流行的解决方案之一就是单线程加上异步回调。其代表派是node.js以及
Java里的新秀Vert.x。
而协程的目的就是当出现长时间的I/O操作时,通过让出目前的协程调度,执行下一个任务的方式,来消除
ContextSwitch上的开销。
协程的特点
线程的切换由操作系统负责调度,协程由用户自己进行调度,因此减少了上下文切换,提高了效率。
线程的默认Stack大小是1M,而协程更轻量,接近1K。因此可以在相同的内存中开启更多的协程。
由于在同一个线程上,因此可以避免竞争关系而使用锁。
适用于被阻塞的,且需要大量并发的场景。但不适用于大量计算的多线程,遇到此种情况,更好实用线程去解
决。
协程的原理
当出现IO阻塞的时候,由协程的调度器进行调度,通过将数据流立刻yield掉(主动让出),并且记录当前栈
上的数据,阻塞完后立刻再通过线程恢复栈,并把阻塞的结果放到这个线程上去跑,这样看上去好像跟写同步
代码没有任何差别,这整个流程可以称为coroutine,而跑在由coroutine负责调度的线程称为Fiber。比
如Golang里的 go关键字其实就是负责开启一个Fiber,让func逻辑跑在上面。
由于协程的暂停完全由程序控制,发生在用户态上;而线程的阻塞状态是由操作系统内核来进行切换,发生在
内核态上。
因此,协程的开销远远小于线程的开销,也就没有了ContextSwitch上的开销。
线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位;
一个进程由一个或多个线程组成,线程是一个进程中代码的不同执行路线;
进程之间相互独立,但同一进程下的各个线程之间共享程序的内存空间(包括代码段、数据集、堆等)及一些进
程级的资源(如打开文件和信号),某进程内的线程在其它进程不可见;
调度和切换:线程上下文切换比进程上下文切换要快得多。
面试题:怎么确定一个程序是 多线程 还是 单线程?
去看该 进程的详细状态
cat /proc/该程序的pid号/status
grep -i threads /proc/该程序的pid号/status
prtstat 该程序的pid号 |grep -i threads
一个进程结束了,但是如果该进程的父进程已经先结束了,那么该进程就不会变成僵尸进程,因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程,看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就由Init来接管它,成为它的父进程,子进程退出后init会回收其占用的相关资源。但是当子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,此时子进程将成为一个僵厂进程。
父进程退出 子进程没有退出 那么这些子进程就没有父进程来管理了, 就变成僵尸进程
范例:僵尸态
[root@centos7 ~]#bash
[root@centos7 ~]#echo $BASHPID
1809
[root@centos7 ~]#echo $PPID
1436
#将父进程设为停止态
[root@centos7 ~]#kill -19 1436
#杀死子进程,使其进入僵尸态
[root@centos7 ~]#kill -9 1809
[root@centos7 ~]#ps aux #可以看到上面图示的结果,STAT为Z,表示为僵尸态
#方法1:恢复父进程
[root@centos7 ~]#kill -18 1436
#方法2:杀死父进程
[root@centos7 ~]#kill -9 1436
#再次观察,可以僵尸态的进程不存在了
[root@centos7 ~]#ps aux
面试题:
如何过滤僵尸进程。
ps aux | grep Z
如何结束僵尸进程(kill 不掉 最快捷有效 重启)
内存泄漏:Memory Leak
指程序中用malloc或new申请了一块内存,但是没有用free或delete将内存释放,导致这块内存一直处于占用状态
内存溢出:Memory Overflow
指程序申请了10M的空间,但是在这个空间写入10M以上字节的数据,就是溢出,类似红杏出墙
内存不足:OOM
OOM 即 Out Of Memory,“内存用完了”,在情况在java程序中比较常见。系统会选一个进程将之杀死,在日志messages中看到类似下面的提示
Jul 10 10:20:30 kernel: Out of memory: Kill process 9527 (java) score 88 or sacrifice child
java 之所以占用内存是因为java在启动时会自带一个虚拟机JVM。
JVM的中文名称叫Java虚拟机,它是由软件技术模拟出计算机运行的一个虚拟的计算机。
JVM在Java程序开始运行的时候,它才运行,程序结束的时它就停止。
JVM也充当着一个翻译官的角色,我们编写出的Java程序,是不能够被操作系统所直接识别的,这时候JVM的作用就体现出来了,它负责把我们的程序翻译给系统“听”,告诉它我们的程序需要做什么操作。
JVM有者垃圾回收功能,当JVM因为没有足够的内存来为对象分配空间并且垃圾回收器也已经没有空间可回收时,就会抛出这个error,因为这个问题已经严重到不足以被应用处理。
原因:
给应用分配内存太少:比如虚拟机本身可使用的内存(一般通过启动时的JVM参数指定)太少。
应用用的太多,并且用完没释放,浪费了。此时就会造成内存泄露或者内存溢出。
使用的解决办法:
1,限制java进程的max heap,并且降低java程序的worker数量,从而降低内存使用
2,给系统增加swap空间
pmap 进程id
[root@localhost ~]#pmap 1143
1143: /usr/sbin/sshd -D
0000555bd6b0f000 800K r-x-- sshd
0000555bd6dd6000 16K r---- sshd
0000555bd6dda000 4K rw--- sshd
0000555bd6ddb000 36K rw--- [ anon ]
0000555bd7603000 132K rw--- [ anon ]
查看进程的内存映像信息
进程的基本状态
创建状态:进程在创建时需要申请一个空白PCB(process control block进程控制块),向其中填写控制和管理进程的信息,完成资源分配。如果创建工作无法完成,比如资源无法满足,就无法被调度运行,把此时进程所处状态称为创建状态
就绪状态:进程已准备好,已分配到所需资源,只要分配到CPU就能够立即运行
执行状态:进程处于就绪状态被调度后,进程进入执行状态
阻塞状态:正在执行的进程由于某些事件(I/O请求,申请缓存区失败)而暂时无法运行,进程受到阻塞。在满足请求时进入就绪状态等待系统调用
终止状态:进程结束,或出现错误,或被系统终止,进入终止状态。无法再执行
状态之间转换六种情况
运行——>就绪:1,主要是进程占用CPU的时间过长,而系统分配给该进程占用CPU的时间是有限的;
2,在采用抢先式优先级调度算法的系统中,当有更高优先级的进程要运行时,该进程就被迫让出CPU,
该进程便由执行状态转变为就绪状态
就绪——>运行:运行的进程的时间片用完,调度就转到就绪队列中选择合适的进程分配CPU
运行——>阻塞:正在执行的进程因发生某等待事件而无法执行,则进程由执行状态变为阻塞状态,如
发生了I/O请求
阻塞——>就绪:进程所等待的事件已经发生,就进入就绪队列
以下两种状态是不可能发生的:
阻塞——>运行:即使给阻塞进程分配CPU,也无法执行,操作系统在进行调度时不会从阻塞队列进行
挑选,而是从就绪队列中选取
就绪——>阻塞:就绪态根本就没有执行,谈不上进入阻塞态
进程更多的状态:
运行态:running
就绪态:ready
睡眠态:分为两种,可中断:interruptable,不可中断:uninterruptable
停止态:stopped,暂停于内存,但不会被调度,除非手动启动
僵死态:zombie,僵尸态,结束进程,父进程结束前,子进程不关闭,杀死父进程可以关闭僵死态 的子进程
进程结束 父进程 会回收子进程的硬件资源
子进程如果出现意外关闭, 父进程无感知就不会收回资源,这个人为关闭父进程, 资源不会回收产生僵尸进程 (范例看2.2)
同一主机:
pipe 管道,单向传输 cmd1 | cmd 2
socket 套接字文件,双工通信
Memory-maped file 文件映射,将文件中的一段数据映射到物理内存,多个进程共享这片内存
shm shared memory 共享内存
signal 信号
Lock 对资源上锁,如果资源已被某进程锁住,则其它进程想修改甚至读取这些资源,都将被阻塞,直到锁被打开
semaphore 信号量,一种计数器
不同主机:socket=IP和端口号
RPC remote procedure call 远程调用
MQ 消息队列,生产者和消费者,如:Kafka,RabbitMQ,ActiveMQ
进程优先级调整
静态优先级:100-139
进程默认启动时的nice值为0,优先级为120
只有根用户才能降低nice值(提高优先性)
ps axo pid,comm,ni
#查看
[root@centos8 ~]#nice -n -10 ping 127.0.0.1
[root@centos7 ~]#renice -n -20 2118
操作系统分类:
协作式多任务:早期 windows 系统使用,即一个任务得到了 CPU 时间,除非它自己放弃使用CPU ,否则将完全霸占 CPU ,所以任务之间需要协作——使用一段时间的 CPU ,主动放弃使用
抢占式多任务:Linux内核,CPU的总控制权在操作系统手中,操作系统会轮流询问每一个任务是否需要使用 CPU ,需要使用的话就让它用,不过在一定时间后,操作系统会剥夺当前任务的 CPU 使用权,把它排在询问队列的最后,再去询问下一个任务
进程类型:
守护进程: daemon,在系统引导过程中启动的进程,和终端无关进程
前台进程:跟终端相关,通过终端启动的进程
注意:两者可相互转化
按进程资源使用的分类:
CPU-Bound:CPU 密集型,非交互
IO-Bound:IO 密集型,交互
进程的管理主要是指进程的关闭与重启。我们一般关闭或重启软件,都是关闭或重启它的程序,而不是直接操作进程的。比如,要重启 apache 服务,一般使用命令"systemctl start httpd"重启 apache的程序。 service httpd restart
那么,可以通过直接管理进程来关闭或重启 apache 吗?答案是肯定的,这时就要依赖进程的信号(Signal)了。我们需要给予该进程 信号,告诉进程我们想要让它做什么。
系统中可以识别的信号较多,我们可以使用命令"kill -l"或"man 7 signal"来查询
号代号 | 信号名称 | 说 明 |
---|---|---|
1 | SIGHUP | 该信号让进程立即关闭.然后重新读取配置文件之后重启 |
2 | SIGINT | 程序中止信号,用于中止前台进程。相当于输出 Ctrl+C 快捷键 |
3 | SIGQUIT | 退出 |
8 | SIGFPE | 在发生致命的算术运算错误时发出。不仅包括浮点运算错误,还包括溢出及除数为 0 等其他所有的算术运算错误 |
9 | SIGKILL | 用来立即结束程序的运行。本信号不能被阻塞、处理和忽略。般用于强制中止进程 |
14 | SIGALRM | 时钟定时信号,计算的是实际的时间或时钟时间。alarm 函数使用该信号 |
15 | SIGTERM | 正常结束进程的信号,kill 命令的默认信号。如果进程已经发生了问题,那么这 个信号是无法正常中止进程的,这时我们才会尝试 SIGKILL 信号,也就是信号 9 |
18 | SIGCONT | 该信号可以让暂停的进程恢复执行。本信号不能被阻断 |
19 | SIGSTOP | 该信号可以暂停前台进程,相当于输入 Ctrl+Z 快捷键。本信号不能被阻断 |
ps 即 process state,可以查看进程当前状态的快照,默认显示当前终端中的进程,Linux系统各进程的相关信息均保存在/proc/该程序的pid号 数字目录/status 下的文件中
支持三种选项:
UNIX选项 如: -A -e
GNU选项 如: --help
BSD选项 如: a
查看静态的进程统计信息
"ps aux" 可以查看系统中所有的进程;
"ps -le" 可以查看系统中所有的进程,而且还能看到进程的父进程的 PID 和进程优先级;
"ps -l" 只能看到当前 Shell 产生的进程;
常用选项
a:显示当前终端下的所有进程信息,包括其他用户的进程。与“x”选项结合时将示系统中所有的进程信息。
u:使用以用户为主的格式输出进程信息。
x:显示当前用户在所有终端下的进程信息。
-e:显示系统内的所有进程信息。
-l:使用长(Long)格式显示进程信息。
-f:使用完整的(Full)格式显示进程信
k|--sort 属性 对属性排序,属性前加 - 表示倒序 ps aux k -%cpu
o 属性… 选项显示定制的信息 pid、cmd、%cpu、%mem
ps 输出属性
C : ps -ef 显示列 C 表示cpu利用率
VSZ: Virtual memory SiZe,虚拟内存集,线性内存
RSS: ReSident Size, 常驻内存集
STAT:进程状态
R:running
S: interruptable sleeping
D: uninterruptable sleeping
T: stopped
Z: zombie
+: 前台进程
l: 多线程进程
L:内存分页并带锁
N:低优先级进程
<: 高优先级进程
s: session leader,会话(子进程)发起者
I:Idle kernel thread,CentOS 8 新特性
ni: nice值
pri: priority 优先级
rtprio: 实时优先级
psr: processor CPU编号
ps axo pid,cmd,psr,ni,pri,rtprio
实例:
ps a
ps -a
#风格不同 显示结果不同
ps
#显示当前终端中的进程
ps a
#看到所有
ps ax
#终端有关或无关的进程
ps aux
#u和用户有关等详细信息
表头 | 含义 |
---|---|
USER | 该进程是由哪个用户产生的。 |
PID | 进程的 ID。 |
%CPU | 该进程占用 CPU 资源的百分比,占用的百分比越高,进程越耗费资源。 |
%MEM | 该进程占用物理内存的百分比,占用的百分比越高,进程越耗费资源。 |
VSZ | 该进程占用虚拟内存的大小,单位为 KB。 |
RSS | 该进程占用实际物理内存的大小,单位为 KB。 |
TTY | 该进程是在哪个终端运行的。其中,tty1 ~ tty7 代表本地控制台终端(可以通过 Alt+F1 ~ F7 快捷键切换不同的终端),tty1~tty6 是本地的字符界面终端,tty7 是图形终端。pts/0 ~ 255 代表虚拟终端,一般是远程连接的终端,第一个远程连接占用 pts/0,第二个远程连接占用 pts/1,依次増长。?代表和终端无关,系统进程 |
STAT | 进程状态。常见的状态有以下几种: -D:不可被唤醒的睡眠状态,通常用于 I/O 情况。 -R:该进程正在运行。 -S:该进程处于睡眠状态,可被唤醒。 -T:停止状态,可能是在后台暂停或进程处于除错状态。 -W:内存交互状态(从 2.6 内核开始无效)。 -X:死掉的进程(应该不会出现)。 -Z:僵尸进程。进程已经中止,但是还是占用硬件资源。 -<:高优先级(以下状态在 BSD 格式中出现)。 -N:低优先级。 -L:被锁入内存。 -s:包含子进程。 -l:多线程(小写 L)。 -+:位于后台。 |
START | 该进程的启动时间。 |
TIME | 该进程占用 CPU 的运算时间,注意不是系统时间。 |
COMMAND | 产生此进程的命令名。 |
ps -el 命令输出信息
表头 | 含义 |
---|---|
F | 进程标志,说明进程的权限,常见的标志有两个: 1:进程可以被复制,但是不能被执行;4:进程使用超级用户权限; |
S | 进程状态。具体的状态和"psaux"命令中的 STAT 状态一致; |
UID | 运行此进程的用户的 ID; |
PID | 进程的 ID; |
PPID | 父进程的 ID; |
C | 该进程的 CPU 使用率,单位是百分比; |
PRI | 进程的优先级,数值越小,该进程的优先级越高,越早被 CPU 执行;系统定义不可以人为修改 |
NI | 进程的优先级,数值越小,该进程越早被执行;可以人为修改 |
ADDR | 该进程在内存的哪个位置; |
SZ | 该进程占用多大内存; |
WCHAN | 该进程是否运行。"-"代表正在运行; |
TTY | 该进程由哪个终端产生; |
TIME | 该进程占用 CPU 的运算时间,注意不是系统时间; |
CMD | 产生此进程的命令名; |
如果不想看到所有的进程,只想查看一下当前登录产生了哪些进程,那只需使用 "ps -l" 命令就足够了
Linux 是一个多用户、多任务的操作系统,系统中通常运行着非常多的进程。但是 CPU 在一个时钟周期内只能运算一条指令(现在的 CPU 采用了多线程、多核心技术,所以在一个时钟周期内可以运算多条指令。 但是同时运算的指令数也远远小于系统中的进程总数),那问题来了:谁应该先运算,谁应该后运算呢?这就需要由进程的优先级来决定了。
另外,CPU 在运算数据时,不是把一个集成算完成,再进行下一个进程的运算,而是先运算进程 1,再运算进程 2,接下来运算进程 3,然后再运算进程 1,直到进程任务结束。不仅如此,由于进程优先级的存在,进程并不是依次运算的,而是哪个进程的优先级高,哪个进程会在一次运算循环中被更多次地运算。
这样说很难理解,我们换一种说法。假设我现在有 4 个孩子(进程)需要喂饭(运算),我更喜欢孩子 1(进程 1 优先级更高),孩子 2、孩子 3 和孩子 4 一视同仁(进程 2、进程 3 和进程 4 的优先级一致)。现在我开始喂饭了,我不能先把孩子 1 喂饱,再喂其他的孩子,而是需要循环喂饭(CPU 运算时所有进程循环运算)。那么,我在喂饭时(运算),会先喂孩子 1 一口饭,然后再去喂其他孩子。而且在一次循环中,先喂孩子 1 两口饭,因为我更喜欢孩子 1(优先级高),而喂其他的孩子一口饭。这样,孩子 1 会先吃饱(进程 1 运算得更快),因为我更喜欢孩子 1。
在 Linux 系统中,表示进程优先级的有两个参数:Priority 和 Nice
其中,PRI 代表 Priority,NI 代表 Nice。这两个值都表示优先级,数值越小代表该进程越优先被 CPU 处理。不过,PRI值是由内核动态调整的,用户不能直接修改。所以我们只能通过修改 NI 值来影响 PRI 值,间接地调整进程优先级。
PRI 和 NI 的关系如下:
PRI (最终值) = PRI (原始值) + NI
ps axo pid,cmd,ni
#查看
[root@centos8 ~]#nice -n -10 ping 127.0.0.1
[root@centos7 ~]#renice -n -20 2118
其实,大家只需要记得,我们修改 NI 的值就可以改变进程的优先级即可。NI 值越小,进程的 PRI 就会降低,该进程就越优先被 CPU 处理;反之,NI 值越大,进程的 PRI 值就会増加,该进程就越靠后被 CPU 处理。
修改 NI 值时有几个注意事项:
NI 范围是 -20~19。
普通用户调整 NI 值的范围是 0~19,而且只能调整自己的进程。
普通用户只能调高 NI 值,而不能降低。如原本 NI 值为 0,则只能调整为大于 0。
只有 root 用户才能设定进程 NI 值为负值,而且可以调整任何用户的进程。
#查看进程的特定属性
ps axo pid,cmd,%mem,%cpu
#按CPU利用率倒序排序
ps aux k -%cpu
a :所有终端
u :以用户格式
x :所有进程
k :排序
-%cpu 倒序
#模拟cpu忙
dd if=/dev/zero of=/dev/null
#排序,查找占用最多内存和CPU的进程
ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head
ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%cpu | head
#按内存倒序排序
ps axo pid,cmd,%cpu,%mem --sort %mem
#prtstat 18395
面试题:找到未知进程的执行程序文件路径
[root@localhost ~]#ps aux k -%cpu |head
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
zhangsan 26314 102 0.0 108096 616 pts/2 R+ 10:18 0:28 dd if=/dev/zero of=/dev/null
[root@localhost ~]#ll /proc/26314/exe
[root@localhost ~]#touch a;chattr +i a
prtstat 进程的pid号
prtstat 18395
ps 命令可以一次性给出当前系统中进程状态,但使用此方式得到的信息缺乏时效性,并且,如果管理员需要实时监控进程运行情况,就必须不停地执行 ps 命令,这显然是缺乏效率的。
为此,Linux 提供了 top 命令。top 命令可以动态地持续监听进程地运行状态,与此同时,该命令还提供了一个交互界面,用户可以根据需要,人性化地定制自己的输出,进而更清楚地了进程的运行状态。
选项:
-d 秒数:指定 top 命令每隔几秒更新。默认是 3 秒;
-b:使用批处理模式输出。一般和"-n"选项合用,用于把 top 命令重定向到文件中;
-n 次数:指定 top 命令执行的次数。一般和"-"选项合用;
-p 进程PID:仅查看指定 ID 的进程;
-s:使 top 命令在安全模式中运行,避免在交互模式中出现错误;
-u 用户名:只监听某个用户的进程;
在 top 命令的显示窗口中,还可以使用如下按键,进行一下交互操作:
? 或 h:显示交互模式的帮助;
c:按照 CPU 的使用率排序,默认就是此选项;
M:按照内存的使用率排序;
N:按照 PID 排序;
T:按照 CPU 的累积运算时间排序,也就是按照 TIME+ 项排序;
k:按照 PID 给予某个进程一个信号。一般用于中止某个进程,信号 9 是强制中止的信号;
r:按照 PID 给某个进程重设优先级(Nice)值;
q:退出 top 命令;
首部信息显示(对显示界面进行操作):
x uptime信息:l命令
tasks及cpu信息:t命令
cpu分别显示:1 (数字)
memory信息:m命令
退出命令:q
修改刷新时间间隔:s
终止指定进程:k
保存文件:W
top 命令的输出内容是动态的,默认每隔 3 秒刷新一次。命令的输出主要分为两部分:
第一部分是前五行,显示的是整个系统的资源使用状况,我们就是通过这些输出来判断服务器的资源使用状态的;
第二部分从第六行开始,显示的是系统中进程的信息;
第一行为任务队列信息,具体内容如表 所示。
内 容 | 说 明 |
---|---|
16:04:35 | 系统当前时间 |
up 4 min | 系统的运行时间.本机己经运行 4 分钟 |
1 users | 当前登录了一个用户 |
load average: 0.00,0.00,0.00 | 系统在之前 1 分钟、5 分钟、15 分钟的平均负载。如果 CPU 是单核的,则这个数值超过 1 就是高负载:如果 CPU 是四核的,则这个数值超过 4 就是高负载 (这个平均负载完全是依据个人经验来进行判断的,一般认为不应该超过服务器 CPU 的核数) |
第二行为进程信息,具体内容如表
内 容 | 说 明 |
---|---|
Tasks: 176 total | 系统中的进程总数 |
1 running | 正在运行的进程数 |
175 sleeping | 睡眠的进程数 |
0 stopped | 正在停止的进程数 |
0 zombie | 僵尸进程数。如果不是 0,则需要手工检查僵尸进程 |
第三行为 CPU 信息,具体内容如表
内 容 | 说 明 |
---|---|
Cpu(s): 0.1 %us | 用户模式占用的 CPU 百分比 个人用户开启的进程占用的 cpu 率 |
0.1%sy | 系统模式占用的 CPU 百分比 |
0.0%ni | 改变过优先级的用户进程占用的 CPU 百分比 |
99.7%id | 空闲 CPU 占用的 CPU 百分比 |
0.1%wa | 等待输入/输出的进程占用的 CPU 百分比 1 |
0.0%hi | 硬中断请求服务占用的 CPU 百分比 |
0.1%si | 软中断请求服务占用的 CPU 百分比 |
0.0%st | st(steal time)意为虚拟程序占用 cpu 时间百分比,就是当有虚拟机时,虚拟 CPU 等待实际 CPU 的时间百分比 |
第四行为物理内存信息,具体内容如表buff cache
内 容 | 说 明 |
---|---|
Mem: 1867048k total | 物理内存的总量,单位为KB |
1185708k free | 空闲的物理内存数量。 |
292996k used | 己经使用的物理内存数量 |
388344k buff/cache | 作为缓冲的内存数量 |
第五行为交换分区(swap)信息,如表
内 容 | 说 明 |
---|---|
Swap: 4243452k total | 交换分区(虚拟内存)的总大小 |
4243452k free | 空闲交换分区的大小 |
0 k used | 已经使用的交换分区的大小 |
1368568k avail Mem | 代表可用于进程下一次分配的物理内存数量 |
通过 top 命令的第一部分就可以判断服务器的健康状态。如果 1 分钟、5 分钟、15 分钟的平均负载高于 1,则证明系统压力较大。如果 CPU 的使用率过高或空闲率过低,则证明系统压力较大。如果物理内存的空闲内存过小,则也证明系统压力较大。
这时,我们就应该判断是什么进程占用了系统资源。如果是不必要的进程,就应该结束这些进程;如果是必需进程,那么我们该増加服务器资源(比如増加虚拟机内存),或者建立集群服务器。
缓冲(buffer)和缓存(cache)的区别:
缓存(cache)是在读取硬盘中的数据时,把最常用的数据保存在内存的缓存区中,再次读取该数据时,就不去硬盘中读取了,而在缓存中读取。
缓冲(buffer)是在向硬盘写入数据时,先把数据放入缓冲区,然后再一起向硬盘写入,把分散的写操作集中进行,减少磁盘碎片和硬盘的反复寻道,从而提高系统性能。
简单来说,缓存(cache)是用来加速数据从硬盘中"读取"的,而缓冲(buffer)是用来加速数据"写入"硬盘的。
top 命令的第二部分输出,主要是系统进程信息,各个字段的含义如下:
PID | 进程的 ID。 |
USER | 该进程所属的用户。 |
PR | 优先级,数值越小优先级越高 |
NI | 优先级,数值越小、优先级越高 |
VIRT | 该进程使用的虚拟内存的大小,单位为 KB。 |
RES | 该进程使用的物理内存的大小,单位为 KB。 |
SHR | 共享内存大小,单位为 KB。 |
S | 进程状态。 |
%CPU | 该进程占用 CPU 的百分比。 |
%MEM | 该进程占用内存的百分比。 |
TIME+ | 该进程共占用的 CPU 时间。 |
COMMAND | 进程的命令名。 |
排序:
P:以占据的CPU百分比,%CPU
M:占据内存百分比,%MEM
T:累积占据CPU时长,TIME+
首部信息显示:
uptime信息:l命令
tasks及cpu信息:t命令
cpu分别显示:1 (数字)
memory信息:m命令
退出命令:q
修改刷新时间间隔:s
终止指定进程:k
保存文件:W
[root@test ~]# top
top - 09:36:19 up 1:02, 2 users, load average: 0.00, 0.01, 0.05
Tasks: 157 total, 1 running, 156 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 25.9/2031912 [||||||||||||||||| ]
KiB Swap: 0.0/2097148 [
top命令栏位信息简介
us:用户空间
sy:内核空间
ni:调整nice时间
id:空闲
wa:等待IO时间
hi:硬中断
si:软中断(模式切换)
st:虚拟机偷走的时间
top选项:
-d # 指定刷新时间间隔,默认为3秒
-b 全部显示所有进程
-n # 刷新多少次后退出
查看指定的进程
-U 指定用户
-l: 显示进程名
-a: 显示完整格式的进程名
-P pid: 显示指定进程的子进程
[root@test ~]# pgrep -l "log"
# 显示进程名
435 xfs-log/dm-0
713 xfs-log/sda1
790 xfs-log/md5
877 systemd-logind
885 abrt-watch-log
886 abrt-watch-log
890 rsyslogd
[root@test ~]# pgrep -l -U zhangsan
#指定用户
uptime
[root@localhost ~]#uptime
10:36:45 up 5:02, 2 users, load average: 0.97, 0.50, 0.23
已知程序名不知道pid号
[root@localhost ~]#pidof nginx
#查看 nginx进程的 pid 号
22142 22002
以树形结构列出进程信息
pstree [OPTION] [ PID | USER ]
常用选项
-a 显示启动每个进程对应的完整指令,包括启动进程的路径、参数等
-p 显示PID
-T 不显示线程thread,默认显示线程
-u 显示用户切换
-H pid 高亮显示指定进程及其前辈进程
[root@test ~]# pstree 1
#查看进程号为1的进程
[root@test ~]# pstree lisi
#查看用户lisi的进程
[root@test ~]# pstree -pH 1780
#高亮
lsof 命令,“list opened files”的缩写,直译过来,就是列举系统中已经被打开的文件。通过 lsof 命令,我们就可以根据文件找到对应的进程信息,也可以根据进程信息找到进程打开的文件。
lsof [选项]
选项 | 功能 |
---|---|
-c 字符串 | 只列出以字符串开头的进程打开的文件。 |
+d 目录名 | 列出某个目录中所有被进程调用的文件。 |
-u 用户名 | 只列出某个用户的进程打开的文件。 |
-p pid | 列出某个 PID 进程打开的文件。 |
-i | 用以显示符合条件的进程情况 |
[root@localhost ~]# lsof | more
#查询系统中所有进程调用的文件
误删文件可以找回
有人在使用
lsof |grep delete
cupsd 1144(pid) root 10r REG 253,0 2337 9381005 /etc/passwd+ (deleted)
ll /proc/1144/fd
fd 是文件描述符
[root@localhost data]#ll /proc/1144/fd
总用量 0
lr-x------. 1 root root 64 11月 29 11:26 0 -> /dev/null
lrwx------. 1 root root 64 11月 29 11:26 1 -> socket:[20288]
lr-x------. 1 root root 64 11月 29 11:26 10 -> /etc/passwd+ (deleted)
lrwx------. 1 root root 64 11月 29 11:26 11 -> socket:[24022]
lrwx------. 1 root root 64 11月 29 11:26 12 -> socket:[24023]
cat /proc/1144/fd/10
如果你想动态的了解一下系统资源的使用状况,以及查看当前系统中到底是哪个环节最占用系统资源,就可以使用 vmstat 命令。
vmstat命令,是 Virtual Meomory Statistics(虚拟内存统计)的缩写,可用来监控 CPU 使用、进程状态、内存使用、虚拟内存使用、硬盘输入/输出状态等信息。
[root@localhost ~]# vmstat [-a] [刷新延时 刷新次数]
[root@localhost ~]# vmstat [选项]
[root@localhost proc]# vmstat 1 3
#使用vmstat检测,每隔1秒刷新一次,共刷新3次
下表罗列出了 vmstat 命令的第二种基本格式中常用的选项及各自的含义。
选项 | 含义 |
---|---|
-fs | -f:显示从启动到目前为止,系统复制(fork)的程序数,此信息是从 /proc/stat 中的 processes 字段中取得的。 -s:将从启动到目前为止,由一些事件导致的内存变化情况列表说明。 |
-S 单位 | 令输出的数据显示单位,例如用 K/M 取代 bytes 的容量。 |
-d | 列出硬盘有关读写总量的统计表。 |
-p 分区设备文件名 | 查看硬盘分区的读写情况。 |
字段 | 含义 |
---|---|
procs | 进程信息字段: -r:等待运行的进程数,数量越大,系统越繁忙。 -b:不可被唤醒的进程数量,数量越大,系统越繁忙。 |
memory | 内存信息字段: -swpd:虚拟内存的使用情况,单位为 KB。 -free:空闲的内存容量,单位为 KB。-buff:缓冲的内存容量,单位为 KB。-cache:缓存的内存容量,单位为 KB。 |
swap | 交换分区信息字段: -si:从磁盘中交换到内存中数据的数量,单位为 KB。 -so:从内存中交换到磁盘中数据的数量,单位为 KB。这两个数越大,表明数据需要经常在磁盘和内存之间进行交换,系统性能越差。 |
io | 磁盘读/写信息字段: -bi:从块设备中读入的数据的总量,单位是块。 -bo:写到块设备的数据的总量,单位是块。这两个数越大,代表系统的 I/O 越繁忙。 |
system | 系统信息字段: -in:每秒被中断的进程次数。 -cs:每秒进行的事件切换次数。这两个数越大,代表系统与接口设备的通信越繁忙。 |
cpu | CPU信息字段: -us:非内核进程消耗 CPU 运算时间的百分比。 -sy:内核进程消耗 CPU 运算时间的百分比。 -id:空闲 CPU 的百分比。 -wa:等待 I/O 所消耗的 CPU 百分比。 -st:被虚拟机所盗用的 CPU 百分比 |
通过分析 vmstat 命令的执行结果,可以获得一些与当前 Linux 运行性能相关的信息。比如说:
r 列表示运行和等待 CPU 时间片的进程数,如果这个值长期大于系统 CPU 的个数,就说明 CPU 不足,需要增加 CPU。
b 表示不可中断睡眠的进程
swpd 列表示切换到内存交换区的内存数量(以 kB 为单位)。如果 swpd 的值不为 0,或者比较大,而且 si、so 的值长期为 0,那么这种情况下一般不用担心,不用影响系统性能。
cache 列表示缓存的内存数量,一般作为文件系统缓存,频繁访问的文件都会被缓存。如果缓存值较大,就说明缓存的文件数较多,如果此时 I/O 中 bi 比较小,就表明文件系统效率比较好。
一般情况下,si(数据由硬盘调入内存)、so(数据由内存调入硬盘) 的值都为 0,如果 si、so 的值长期不为 0,则表示系统内存不足,需要增加系统内存。
如果 bi+bo 的参考值为 1000 甚至超过 1000,而且 wa 值较大,则表示系统磁盘 I/O 有问题,应该考虑提高磁盘的读写性能。
输出结果中,CPU 项显示了 CPU 的使用状态,其中当 us 列的值较高时,说明用户进程消耗的 CPU 时间多,如果其长期大于 50%,就需要考虑优化程序或算法;sy 列的值较高时,说明内核消耗的 CPU 资源较多。通常情况下,us+sy 的参考值为 80%,如果其值大于 80%,则表明可能存在 CPU 资源不足的情况。
总的来说,vmstat 命令的输出结果中,我们应该重点注意 procs 项中 r 列的值,以及 CPU 项中 us 列、sy 列和 id 列的值。
例子:
dd if=/dev/zero of=/dev/null bs=4G
[root@localhost ~]#vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 1456624 0 161284 0 0 131 17 44 46 0 0 100 0 0
dd if=/dev/sda of=/dev/null
查看内存使用情况 :free
free -h #超过1G用G为单位查看,其它以m为单位查看
free -m #以m为单位查看
一台服务器买来后一个星期就开始卡,怎么解决
echo 3 > /proc/sys/vm/drop_caches
#清除缓存
pmap 1073
查看进程占用 内存的详细信息
iostat 可以 提供更丰富的IO性能状态数据 和 硬盘读写性能。
常用选项:
-c 只显示CPU行
-d 显示设备〈磁盘)使用状态
-k 以千字节为为单位显示输出
-t 在输出中包括时间戳
-x 在输出中包括扩展的磁盘指标
例子:
[root@localhost ~]#iostat 1 -d /dev/sda
#只看 sda硬盘 并每一秒显示一次。
[root@localhost ~]#iostat 1 -d /dev/sda
Linux 3.10.0-693.el7.x86_64 (localhost.localdomain) 2024年01月04日 _x86_64_ (4 CPU)
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 0.56 17.43 1.20 363463 24956
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 0.00 0.00 0.00 0 0
iotop
iftop -ni ens33
#网络流量
网页客户端
wget https://prdownloads.sourceforge.net/webadmin/webmin-1.955-1.noarch.rpm
yum -y install webmin-1.955-1.noarch.rpm
service webmin start
ss -ntl
默认用户:root 密码:123
[root@localhost data]#uptime
22:03:10 up 6:03, 2 users, load average: 0.00, 0.06, 0.10
当前时间 运行时间 登录用户
[root@localhost ~]#mpstat
Linux 3.10.0-693.el7.x86_64 (localhost.localdomain) 2023年07月27日 _x86_64_ (4 CPU)
01时31分37秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
01时31分37秒 all 0.71 0.00 1.08 0.75 0.00 0.04 0.00 0.00 0.00 97.41
当前时间 用户空间 ni优先级 系统内核 盗取时间 系统空闲
盗取时间和虚拟化有关
[root@localhost ~]#mpstat 1 3
#1秒 一次 看3次
yum install dstat -y
官网:http://www.webmin.com/
yum install webmin-2.100-1.noarch.rpm -y
rpm -q webmin
systemctl start webmin
systemctl status webmin
https://自己虚拟机的ip地址:10000/
root
自己系统的密码
前台启动:通过终端启动,且启动后一直占据终端。影响当前终端操作
后台启动:可通过终端启动,但启动后即转入后台运行(释放终端)
Linux 命令放入后台的方法有两种,分别介绍如下。
后台操作可以 并行执行。
放入后台 运行 命令 &
jobs : 可以看到后台运行的命令列表
fg 1 :把任务调回前台
ctrl + z :放入后台并停止
bg 1 :开启后台任务
kill 后台名 :结束
[root@localhost ~]#dd if=/dev/zero of=/dev/null &
[1] 4592
[root@localhost ~]#top
#使用Ctrl+Z组合键
top - 23:59:39 up 2:36, 5 users, load average: 0.04, 0.03, 0.05
Tasks: 205 total, 1 running, 203 sleeping, 1 stopped, 0 zombie
%Cpu(s): 1.6 us, 1.6 sy, 0.0 ni, 96.9 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1867048 total, 620960 free, 653916 used, 592172 buff/cache
KiB Swap: 4194300 total, 4194300 free, 0 used. 1010568 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 191056 4048 2532 S 0.0 0.2 0:01.02 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.01 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:00.02 ksoftirqd/0
[2]+ Stopped top
[root@localhost ~]#jobs
[1]- Stopped cp -i -r /data/* /opt/
[2]+ Stopped top
[root@localhost ~]#fg 1
#fg 加上序号
fg [[%]JOB_NUM]:把指定的后台作业调回前台
bg [[%]JOB_NUM]:让送往后台的作业在后台继续运行
kill [%JOB_NUM]: 终止指定的作业
& 的并行执行任务
[root@localhost ~]#ping 127.0.0.1&ping 127.0.0.2&ping 127.0.0.3&
killall ping
nohup: 忽略输入并把输出追加到"nohup.out"
nohup ping 127.0.0.1
ping 1-254 网络地址脚本 并 后台运行。 前台一个一个ping很慢。
#!/bin/bash
host="192.168.91."
for i in {1..254}
do
{
ping -c1 -w1 $host$i &>/dev/null && echo $host$i is up || echo $host$i is down
}&
done
wait
kill 从字面来看,就是用来杀死进程的命令,但事实上,这个或多或少带有一定的误导性。从本质上讲,kill 命令只是用来向进程发送一个信号,至于这个信号是什么,是用户指定的。
也就是说,kill 命令的执行原理是这样的,kill 命令会向操作系统内核发送一个信号(多是终止信号)和目标进程的 PID,然后系统内核根据收到的信号类型,对指定进程进行相应的操作。
kill [信号] PID
kill 命令是按照 PID 来确定进程的,所以 kill 命令只能识别 PID,而不能识别进程名。Linux 定义了几十种不同类型的信号,读者可以使用 kill -l 命令查看所有信号及其编号,这里仅列出几个常用的信号
1) SIGHUP 无须关闭进程而让其重读配置文件
2) SIGINT 中止正在运行的进程;相当于Ctrl+c 3) SIGQUIT 相当于ctrl+\ 9) SIGKILL 强制杀死正在运行的进程,可能会导致数据丢失,慎用!
9) 关电源 数据库 写 强制杀死进程
15) SIGTERM 终止正在运行的进程,默认信号
18) SIGCONT 继续运行
19) SIGSTOP 后台休眠
信号编号 | 信号名 | 含义 |
---|---|---|
0 | EXIT | 程序退出时收到该信息。 |
1 | HUP | 挂掉电话线或终端连接的挂起信号,这个信号也会造成某些进程在没有终止的情况下重新初始化。 |
2 | INT | 表示结束进程,但并不是强制性的,常用的 "Ctrl+C" 组合键发出就是一个 kill -2 的信号。 |
3 | QUIT | 退出。 |
9 | KILL | 杀死进程,即强制结束进程。有掉数据的风险 |
11 | SEGV | 段错误。 |
15 | TERM | 正常结束进程,是 kill 命令的默认信号。 |
[root@localhost data]#trap -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
killall 也是用于关闭进程的一个命令,但和 kill 不同的是,killall 命令不再依靠 PID 来杀死单个进程,而是通过程序的进程名来杀死一类进程,也正是由于这一点,该命令常与 ps、pstree 等命令配合使用
killall [选项] [信号] 进程名
-i:交互式,询问是否要杀死某个进程;
-I:忽略进程名的大小写;
killall -i sshd
#交互杀死 sshd
当作于管理进程时,pkill 命令和 killall 命令的用法相同,都是通过进程名杀死一类进程,该命令的基本格式如下:
pkill [信号] 进程名
pkill命令踢出登陆用户
pkill [-t 终端号] 进程名
-U:根据进程所属的用户名终止相应进程
-t:根据进程所在的终端终止相应进程
-SIGNAL
-u uid: effective user,生效者
-U uid: real user,真正发起运行命令者
-t terminal: 与指定终端相关的进程
-l: 显示进程名(pgrep可用)
-a: 显示完整格式的进程名(pgrep可用)
-P pid: 显示指定进程的子进程
使用 killall 命令时,不知道大家发现没有,通过 killall 命令杀死 sshd 进程的方式来踢出用户,非常容易误杀死进程,要么会把 sshd 服务杀死,要么会把自己的登录终端杀死。
所以,不管是使用 kill 命令按照 PID 杀死登录进程,还是使用 killall 命令按照进程名杀死登录进程,都是非常容易误杀死进程的,而使用 pkill 命令则不会
at 工具
由包 at 提供
依赖与atd服务,需要启动才能实现at任务
at队列存放在/var/spool/at目录中,ubuntu存放在/var/spool/cron/atjobs目录下
执行任务时PATH变量的值和当前定义任务的用户身份一致
at 时间
mkdir /aa
ctrl +d 提交
atq 可以查看任务列表
atrm 任务序列号 可以删除任务
at 命令的访问控制是依靠 /etc/at.allow(白名单)和 /etc/at.deny(黑名单)这两个文件来实现的,具体规则如下:
如果系统中有 /etc/at.allow 文件,那么只有写入 /etc/at.allow 文件(白名单)中的用户可以使用 at 命令,其他用户不能使用 at 命令(注意,/etc/at.allow 文件的优先级更高,也就是说,如果同一个用户既写入 /etc/at.allow 文件,又写入 /etc/at.deny 文件,那么这个用户是可以使用 at 命令的)。
如果系统中没有 /etc/at.allow 文件,只有 /etc/at.deny 文件,那么写入 /etc/at.deny 文件(黑名单)中的用户不能使用 at 命令,其他用户可以使用 at 命令。不过这个文件对 root 用户不生效。
如果系统中这两个文件都不存在,那么只有 root 用户可以使用 at 命令。
系统中默认只有 /etc/at.deny 文件,而且这个文件是空的,因此,系统中所有的用户都可以使用 at 命令。不过,如果我们打算控制用户的 at 命令权限,那么只需把用户写入 /etc/at.deny 文件即可
at [option] TIME
at [选项] [时间]
[HH:MM] [yyyy-mm-dd]
HH:MM 在今日的 HH:MM 进行,若该时刻已过,则明天此时执行任务
02:00
HH:MM YYYY-MM-DD 规定在某年某月的某一天的特殊时刻进行该项任务
02:00 2023-10-20
HH:MM[am|pm] [Month] [Date]
06pm March 17
17:20 tomorrow
HH:MM[am|pm] + number [minutes|hours|days|weeks], 在某个时间点再加几个时间后才进行该
项任务
now + 5 min
02pm + 3 days
at 时间
mkdir /aa
ctrl +d 提交
atq 可以查看任务列表
atrm 任务序列号 可以删除任务
[root@localhost ~]# rpm -q at
at-3.1.13-20.el7x86_64
[root@localhost ~]# atq
9 2013-07-26 02:00 a root
#说明root用户有一个at任务在2013年7月26日02:00执行,工作号是9
[root@localhost ~]# atrm [工作号]
#删除指定的at任务
格式 | 用法 |
---|---|
HH:MM | 比如 04:00 AM。如果时间已过,则它会在第二天的同一时间执行。 |
Midnight(midnight) | 代表 12:00 AM(也就是 00:00)。 |
Noon(noon) | 代表 12:00 PM(相当于 12:00)。 |
Teatime(teatime)下午茶 | 代表 4:00 PM(相当于 16:00)。 |
英文月名 日期 年份 | 比如 January 15 2018 表示 2018 年 1 月 15 号,年份可有可无。 |
MMDDYY、MM/DD/YY、MM.DD.YY | 比如 011518 表示 2018 年 1 月 15 号。 |
now+时间 | 以 minutes、hours、days 或 weeks 为单位,例如 now+5 days 表示命令在 5 天之后的此时此刻执行。 |
[root@test ~]# at 14:53 2023-07-27
at> touch /opt/file{a..z}.txt //ctrl+d提交
job 2 at Mon Jul 12 10:50:00 2021
[root@test ~]# atq
2 Mon Jul 12 10:50:00 2021 a root
[root@localhost opt]#at now+1min
at> echo $PATH >/data/path
job 3 at Wed Mar 2 01:42:00 2022
crond.service 默认开启的周期性的计划任务服务
#################
crontab [选项] [file]
###############
选项 | 功能 |
---|---|
-u user | 用来设定某个用户的 crontab 服务,例如 "-u demo" 表示设备 demo 用户的 crontab 服务,此选项一般有 root 用户来运行。 |
-e | 编辑某个用户的 crontab 文件内容。如果不指定用户,则表示编辑当前用户的 crontab 文件。 |
-l | 显示某用户的 crontab 文件内容,如果不指定用户,则表示显示当前用户的 crontab 文件内容。 |
-r | 从 /var/spool/cron 删除某用户的 crontab 文件,如果不指定用户,则默认删除当前用户的 crontab 文件。 |
-i | 在删除用户的 crontab 文件时,给确认提示。 |
crontab -e
#进入 crontab 编辑界面。会打开Vim编辑你的任务
* * * * * 执行的任务
这五个必须要有 * 表示任意时间
项目 | 含义 | 范围 |
---|---|---|
第一个"*" | 一小时当中的第几分钟(minute) | 0~59 |
第二个"*" | 一天当中的第几小时(hour) | 0~23 |
第三个"*" | 一个月当中的第几天(day) | 1~31 |
第四个"*" | 一年当中的第几个月(month) | 1~12 |
第五个"*" | 一周当中的星期几(week) | 0~7(0和7都代表星期日) |
在时间表示中,还有一些特殊符号需要学习
特殊符号 | 含义 |
---|---|
*(星号) | 代表任何时间。比如第一个"*"就代表一小时种每分钟都执行一次的意思。 |
,(逗号) | 代表不连续的时间。比如"0 8,12,16***命令"就代表在每天的 8 点 0 分、12 点 0 分、16 点 0 分都执行一次命令。 |
-(中杠) | 代表连续的时间范围。比如"0 5 ** 1-6命令",代表在周一到周六的凌晨 5 点 0 分执行命令。 |
/(正斜线) | 代表每隔多久执行一次。比如"*/10命令",代表每隔 10 分钟就执行一次命令。 |
每月的 1号 15号 30号
* * 1,15,30 * *
中午 12点 - 16点
* 12-16/2 * * *
每 半小时 执行 一次
*/30 * * * *
[root@localhost opt]#cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
创建计划任务
crontab -u zhnagsan -e
#注意权限
*/2 * * * * /usr/bin/cp /etc/passwd /opt/
#每两分钟执行脚本 注意,cp 命令使用绝对路径
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
*/2 * * * * /usr/bin/cp /etc/passwd /opt/
30 2 * * * /bin/cp -a /etc/ /data/etc`date +\%F_\%T`
30 2 * * * /bin/cp -a /etc/ /data/etc`date +‘%F_%T’` 有问题 执行不了
在书写 crontab 定时任务时,需要注意以下几个事项:
6 个选项都不能为空,必须填写。如果不确定,则使用“*”代表任意时间。
crontab 定时任务的最小有效时间是分钟,最大有效时间是月。像 2018 年某时执行、3 点 30 分 30 秒这样的时间都不能被识别。
在定义时间时,日期和星期最好不要在一条定时任务中出现,因为它们都以天为单位,非常容易让管理员混淆。
在定时任务中,不管是直接写命令,还是在脚本中写命令,最好都使用绝对路径。有时使用相对路径的命令会报错。