全網最全 Linux 指令總結,建議收藏!

原文链接:https://javaforall.cn/127878.html

今天,给小伙伴们带来一篇 Linux 命令总结的非常全的文章,也是我们平时工作中使用率非常高的操作命令,命令有点多,建议小伙伴们可以先收藏后阅读。

1.基本命令

uname -m 显示机器的处理器架构
uname -r 显示正在使用的内核版本
dmidecode -q 显示硬件系统部件
(SMBIOS / DMI) hdparm -i /dev/hda 罗列一个磁盘的架构特性
hdparm -tT /dev/sda 在磁盘上执行测试性读取操作系统信息
arch 显示机器的处理器架构
uname -m 显示机器的处理器架构
uname -r 显示正在使用的内核版本
dmidecode -q 显示硬件系统部件 – (SMBIOS / DMI)
hdparm -i /dev/hda 罗列一个磁盘的架构特性
hdparm -tT /dev/sda 在磁盘上执行测试性读取操作
cat /proc/cpuinfo 显示CPU info的信息
cat /proc/interrupts 显示中断
cat /proc/meminfo 校验内存使用
cat /proc/swaps 显示哪些swap被使用
cat /proc/version 显示内核的版本
cat /proc/net/dev 显示网络适配器及统计
cat /proc/mounts 显示已加载的文件系统
lspci -tv 罗列 PCI 设备
lsusb -tv 显示 USB 设备
date 显示系统日期
cal 2007 显示2007年的日历表
date 041217002007.00 设置日期和时间 – 月日时分年.秒
clock -w 将时间修改保存到 BIOS

2.关机
shutdown -h now 关闭系统(1)
init 0 关闭系统(2)
telinit 0 关闭系统(3)
shutdown -h hours:minutes & 按预定时间关闭系统
shutdown -c 取消按预定时间关闭系统
shutdown -r now 重启(1)
reboot 重启(2)
logout 注销

3.文件和目录
cd /home 进入 ‘/ home’ 目录’
cd .. 返回上一级目录
cd ../.. 返回上两级目录
cd 进入个人的主目录
cd ~user1 进入个人的主目录
cd – 返回上次所在的目录
pwd 显示工作路径
ls 查看目录中的文件
ls -F 查看目录中的文件
ls -l 显示文件和目录的详细资料
ls -a 显示隐藏文件
ls *[0-9]* 显示包含数字的文件名和目录名
tree 显示文件和目录由根目录开始的树形结构(1)
lstree 显示文件和目录由根目录开始的树形结构(2)
mkdir dir1 创建一个叫做 ‘dir1′ 的目录’
mkdir dir1 dir2 同时创建两个目录
mkdir -p /tmp/dir1/dir2 创建一个目录树
rm -f file1 删除一个叫做 ‘file1′ 的文件’
rmdir dir1 删除一个叫做 ‘dir1′ 的目录’
rm -rf dir1 删除一个叫做 ‘dir1’ 的目录并同时删除其内容
rm -rf dir1 dir2 同时删除两个目录及它们的内容
mv dir1 new_dir 重命名/移动 一个目录
cp file1 file2 复制一个文件
cp dir/* . 复制一个目录下的所有文件到当前工作目录
cp -a /tmp/dir1 . 复制一个目录到当前工作目录
cp -a dir1 dir2 复制一个目录
ln -s file1 lnk1 创建一个指向文件或目录的软链接
ln file1 lnk1 创建一个指向文件或目录的物理链接
touch -t 0712250000 file1 修改一个文件或目录的时间戳 – (YYMMDDhhmm)
file file1 outputs the mime type of the file as text
iconv -l 列出已知的编码
iconv -f fromEncoding -t toEncoding inputFile > outputFile creates a new from the given input file by assuming it is encoded in fromEncoding and converting it to toEncoding.
find . -maxdepth 1 -name *.jpg -print -exec convert “{}” -resize 80×60 “thumbs/{}” \; batch resize files in the current directory and send them to a thumbnails directory (requires convert from Imagemagick)

4.文件搜索
find / -name file1 从 ‘/’ 开始进入根文件系统搜索文件和目录
find / -user user1 搜索属于用户 ‘user1’ 的文件和目录
find /home/user1 -name \*.bin 在目录 ‘/ home/user1′ 中搜索带有’.bin’ 结尾的文件
find /usr/bin -type f -atime +100 搜索在过去100天内未被使用过的执行文件
find /usr/bin -type f -mtime -10 搜索在10天内被创建或者修改过的文件
find / -name \*.rpm -exec chmod 755 ‘{}’ \; 搜索以 ‘.rpm’ 结尾的文件并定义其权限
find / -xdev -name \*.rpm 搜索以 ‘.rpm’ 结尾的文件,忽略光驱、捷盘等可移动设备
locate \*.ps 寻找以 ‘.ps’ 结尾的文件 – 先运行 ‘updatedb’ 命令
whereis halt 显示一个二进制文件、源码或man的位置
which halt 显示一个二进制文件或可执行文件的完整路径

5.挂载一个文件系统
mount /dev/hda2 /mnt/hda2 挂载一个叫做hda2的盘 – 确定目录 ‘/ mnt/hda2’ 已经存在
umount /dev/hda2 卸载一个叫做hda2的盘 – 先从挂载点 ‘/ mnt/hda2’ 退出
fuser -km /mnt/hda2 当设备繁忙时强制卸载
umount -n /mnt/hda2 运行卸载操作而不写入 /etc/mtab 文件- 当文件为只读或当磁盘写满时非常有用
mount /dev/fd0 /mnt/floppy 挂载一个软盘
mount /dev/cdrom /mnt/cdrom 挂载一个cdrom或dvdrom
mount /dev/hdc /mnt/cdrecorder 挂载一个cdrw或dvdrom
mount /dev/hdb /mnt/cdrecorder 挂载一个cdrw或dvdrom
mount -o loop file.iso /mnt/cdrom 挂载一个文件或ISO镜像文件
mount -t vfat /dev/hda5 /mnt/hda5 挂载一个Windows FAT32文件系统
mount /dev/sda1 /mnt/usbdisk 挂载一个usb 捷盘或闪存设备
mount -t smbfs -o username=user,password=pass //WinClient/share /mnt/share 挂载一个windows网络共享

6.磁盘空间
df -h 显示已经挂载的分区列表
ls -lSr |more 以尺寸大小排列文件和目录
du -sh dir1 估算目录 ‘dir1′ 已经使用的磁盘空间’
du -sk * | sort -rn 以容量大小为依据依次显示文件和目录的大小
rpm -q -a –qf ‘%10{SIZE}t%{NAME}n’ | sort -k1,1n 以大小为依据依次显示已安装的rpm包所使用的空间 (fedora, redhat类系统)
dpkg-query -W -f=’${Installed-Size;10}t${Package}n’ | sort -k1,1n 以大小为依据显示已安装的deb包所使用的空间 (ubuntu, debian类系统)

7.用户和群组
groupadd group_name 创建一个新用户组
groupdel group_name 删除一个用户组
groupmod -n new_group_name old_group_name 重命名一个用户组
useradd -c “Name Surname ” -g admin -d /home/user1 -s /bin/bash user1 创建一个属于 “admin” 用户组的用户
useradd user1 创建一个新用户
userdel -r user1 删除一个用户 ( ‘-r’ 排除主目录)
usermod -c “User FTP” -g system -d /ftp/user1 -s /bin/nologin user1 修改用户属性
passwd 修改口令
passwd user1 修改一个用户的口令 (只允许root执行)
chage -E 2005-12-31 user1 设置用户口令的失效期限
pwck 检查 ‘/etc/passwd’ 的文件格式和语法修正以及存在的用户
grpck 检查 ‘/etc/passwd’ 的文件格式和语法修正以及存在的群组
newgrp group_name 登陆进一个新的群组以改变新创建文件的预设群组

8.文件的权限
– 使用 “+” 设置权限,使用 “-” 用于取消
ls -lh 显示权限
ls /tmp | pr -T5 -W$COLUMNS 将终端划分成5栏显示
chmod ugo+rwx directory1 设置目录的所有人(u)、群组(g)以及其他人(o)以读(r )、写(w)和执行(x)的权限
chmod go-rwx directory1 删除群组(g)与其他人(o)对目录的读写执行权限
chown user1 file1 改变一个文件的所有人属性
chown -R user1 directory1 改变一个目录的所有人属性并同时改变改目录下所有文件的属性
chgrp group1 file1 改变文件的群组
chown user1:group1 file1 改变一个文件的所有人和群组属性
find / -perm -u+s 罗列一个系统中所有使用了SUID控制的文件
chmod u+s /bin/file1 设置一个二进制文件的 SUID 位 – 运行该文件的用户也被赋予和所有者同样的权限
chmod u-s /bin/file1 禁用一个二进制文件的 SUID位
chmod g+s /home/public 设置一个目录的SGID 位 – 类似SUID ,不过这是针对目录的
chmod g-s /home/public 禁用一个目录的 SGID 位
chmod o+t /home/public 设置一个文件的 STIKY 位 – 只允许合法所有人删除文件
chmod o-t /home/public 禁用一个目录的 STIKY 位
chmod +x 文件路径 为所有者、所属组和其他用户添加执行的权限
chmod -x 文件路径 为所有者、所属组和其他用户删除执行的权限
chmod u+x 文件路径 为所有者添加执行的权限
chmod g+x 文件路径 为所属组添加执行的权限
chmod o+x 文件路径 为其他用户添加执行的权限
chmod ug+x 文件路径 为所有者、所属组添加执行的权限
chmod =wx 文件路径 为所有者、所属组和其他用户添加写、执行的权限,取消读权限
chmod ug=wx 文件路径 为所有者、所属组添加写、执行的权限,取消读权限

9.文件的特殊属性
– 使用 “+” 设置权限,使用 “-” 用于取消
chattr +a file1 只允许以追加方式读写文件
chattr +c file1 允许这个文件能被内核自动压缩/解压
chattr +d file1 在进行文件系统备份时,dump程序将忽略这个文件
chattr +i file1 设置成不可变的文件,不能被删除、修改、重命名或者链接
chattr +s file1 允许一个文件被安全地删除
chattr +S file1 一旦应用程序对这个文件执行了写操作,使系统立刻把修改的结果写到磁盘
chattr +u file1 若文件被删除,系统会允许你在以后恢复这个被删除的文件
lsattr 显示特殊的属性

10.打包和压缩文件
bunzip2 file1.bz2 解压一个叫做 ‘file1.bz2’的文件
bzip2 file1 压缩一个叫做 ‘file1’ 的文件
gunzip file1.gz 解压一个叫做 ‘file1.gz’的文件
gzip file1 压缩一个叫做 ‘file1’的文件
gzip -9 file1 最大程度压缩
rar a file1.rar test_file 创建一个叫做 ‘file1.rar’ 的包
rar a file1.rar file1 file2 dir1 同时压缩 ‘file1’, ‘file2’ 以及目录 ‘dir1’
rar x file1.rar 解压rar包
unrar x file1.rar 解压rar包
tar -cvf archive.tar file1 创建一个非压缩的 tarball
tar -cvf archive.tar file1 file2 dir1 创建一个包含了 ‘file1’, ‘file2’ 以及 ‘dir1’的档案文件
tar -tf archive.tar 显示一个包中的内容
tar -xvf archive.tar 释放一个包
tar -xvf archive.tar -C /tmp 将压缩包释放到 /tmp目录下
tar -cvfj archive.tar.bz2 dir1 创建一个bzip2格式的压缩包
tar -xvfj archive.tar.bz2 解压一个bzip2格式的压缩包
tar -cvfz archive.tar.gz dir1 创建一个gzip格式的压缩包
tar -xvfz archive.tar.gz 解压一个gzip格式的压缩包
zip file1.zip file1 创建一个zip格式的压缩包
zip -r file1.zip file1 file2 dir1 将几个文件和目录同时压缩成一个zip格式的压缩包
unzip file1.zip 解压一个zip格式压缩包

11.RPM 包
– (Fedora, Redhat及类似系统)
rpm -ivh package.rpm 安装一个rpm包
rpm -ivh –nodeeps package.rpm 安装一个rpm包而忽略依赖关系警告
rpm -U package.rpm 更新一个rpm包但不改变其配置文件
rpm -F package.rpm 更新一个确定已经安装的rpm包
rpm -e package_name.rpm 删除一个rpm包
rpm -qa 显示系统中所有已经安装的rpm包
rpm -qa | grep httpd 显示所有名称中包含 “httpd” 字样的rpm包
rpm -qi package_name 获取一个已安装包的特殊信息
rpm -qg “System Environment/Daemons” 显示一个组件的rpm包
rpm -ql package_name 显示一个已经安装的rpm包提供的文件列表
rpm -qc package_name 显示一个已经安装的rpm包提供的配置文件列表
rpm -q package_name –whatrequires 显示与一个rpm包存在依赖关系的列表
rpm -q package_name –whatprovides 显示一个rpm包所占的体积
rpm -q package_name –scripts 显示在安装/删除期间所执行的脚本l
rpm -q package_name –changelog 显示一个rpm包的修改历史
rpm -qf /etc/httpd/conf/httpd.conf 确认所给的文件由哪个rpm包所提供
rpm -qp package.rpm -l 显示由一个尚未安装的rpm包提供的文件列表
rpm –import /media/cdrom/RPM-GPG-KEY 导入公钥数字证书
rpm –checksig package.rpm 确认一个rpm包的完整性
rpm -qa gpg-pubkey 确认已安装的所有rpm包的完整性
rpm -V package_name 检查文件尺寸、 许可、类型、所有者、群组、MD5检查以及最后修改时间
rpm -Va 检查系统中所有已安装的rpm包- 小心使用
rpm -Vp package.rpm 确认一个rpm包还未安装
rpm2cpio package.rpm | cpio –extract –make-directories *bin* 从一个rpm包运行可执行文件
rpm -ivh /usr/src/redhat/RPMS/`arch`/package.rpm 从一个rpm源码安装一个构建好的包
rpmbuild –rebuild package_name.src.rpm 从一个rpm源码构建一个 rpm 包
YUM 软件包升级器

– (Fedora, RedHat及类似系统)

yum install package_name 下载并安装一个rpm包
yum localinstall package_name.rpm 将安装一个rpm包,使用你自己的软件仓库为你解决所有依赖关系
yum update package_name.rpm 更新当前系统中所有安装的rpm包
yum update package_name 更新一个rpm包
yum remove package_name 删除一个rpm包
yum list 列出当前系统中安装的所有包
yum search package_name 在rpm仓库中搜寻软件包
yum clean packages 清理rpm缓存删除下载的包
yum clean headers 删除所有头文件
yum clean all 删除所有缓存的包和头文件

13.DEB 包
(Debian, Ubuntu 以及类似系统)
dpkg -i package.deb 安装/更新一个 deb 包
dpkg -r package_name 从系统删除一个 deb 包
dpkg -l 显示系统中所有已经安装的 deb 包
dpkg -l | grep httpd 显示所有名称中包含 “httpd” 字样的deb包
dpkg -s package_name 获得已经安装在系统中一个特殊包的信息
dpkg -L package_name 显示系统中已经安装的一个deb包所提供的文件列表
dpkg –contents package.deb 显示尚未安装的一个包所提供的文件列表
dpkg -S /bin/ping 确认所给的文件由哪个deb包提供
APT 软件工具 (Debian, Ubuntu 以及类似系统)
apt-get install package_name 安装/更新一个 deb 包
apt-cdrom install package_name 从光盘安装/更新一个 deb 包
apt-get update 升级列表中的软件包
apt-get upgrade 升级所有已安装的软件
apt-get remove package_name 从系统删除一个deb包
apt-get check 确认依赖的软件仓库正确
apt-get clean 从下载的软件包中清理缓存
apt-cache search searched-package 返回包含所要搜索字符串的软件包名称

14.查看文件内容
cat file1 从第一个字节开始正向查看文件的内容
tac file1 从最后一行开始反向查看一个文件的内容
more file1 查看一个长文件的内容
less file1 类似于 ‘more’ 命令,但是它允许在文件中和正向操作一样的反向操作
head -2 file1 查看一个文件的前两行
tail -2 file1 查看一个文件的最后两行
tail -f /var/log/messages 实时查看被添加到一个文件中的内容

15.文本处理
cat file1 file2 … | command <> file1_in.txt_or_file1_out.txt general syntax for text manipulation using PIPE, STDIN and STDOUT
cat file1 | command( sed, grep, awk, grep, etc…) > result.txt 合并一个文件的详细说明文本,并将简介写入一个新文件中
cat file1 | command( sed, grep, awk, grep, etc…) >> result.txt 合并一个文件的详细说明文本,并将简介写入一个已有的文件中
grep Aug /var/log/messages 在文件 ‘/var/log/messages’中查找关键词”Aug”
grep ^Aug /var/log/messages 在文件 ‘/var/log/messages’中查找以”Aug”开始的词汇
grep [0-9] /var/log/messages 选择 ‘/var/log/messages’ 文件中所有包含数字的行
grep Aug -R /var/log/* 在目录 ‘/var/log’ 及随后的目录中搜索字符串”Aug”
sed ‘s/stringa1/stringa2/g’ example.txt 将example.txt文件中的 “string1” 替换成 “string2”
sed ‘/^$/d’ example.txt 从example.txt文件中删除所有空白行
sed ‘/ *#/d; /^$/d’ example.txt 从example.txt文件中删除所有注释和空白行
echo ‘esempio’ | tr ‘[:lower:]’ ‘[:upper:]’ 合并上下单元格内容
sed -e ‘1d’ result.txt 从文件example.txt 中排除第一行
sed -n ‘/stringa1/p’ 查看只包含词汇 “string1″的行
sed -e ‘s/ *$//’ example.txt 删除每一行最后的空白字符
sed -e ‘s/stringa1//g’ example.txt 从文档中只删除词汇 “string1” 并保留剩余全部
sed -n ‘1,5p;5q’ example.txt 查看从第一行到第5行内容
sed -n ‘5p;5q’ example.txt 查看第5行
sed -e ‘s/00*/0/g’ example.txt 用单个零替换多个零
cat -n file1 标示文件的行数
cat example.txt | awk ‘NR%2==1’ 删除example.txt文件中的所有偶数行
echo a b c | awk ‘{print $1}’ 查看一行第一栏
echo a b c | awk ‘{print $1,$3}’ 查看一行的第一和第三栏
paste file1 file2 合并两个文件或两栏的内容
paste -d ‘+’ file1 file2 合并两个文件或两栏的内容,中间用”+”区分
sort file1 file2 排序两个文件的内容
sort file1 file2 | uniq 取出两个文件的并集(重复的行只保留一份)
sort file1 file2 | uniq -u 删除交集,留下其他的行
sort file1 file2 | uniq -d 取出两个文件的交集(只留下同时存在于两个文件中的文件)
comm -1 file1 file2 比较两个文件的内容只删除 ‘file1’ 所包含的内容
comm -2 file1 file2 比较两个文件的内容只删除 ‘file2’ 所包含的内容
comm -3 file1 file2 比较两个文件的内容只删除两个文件共有的部分

16.字符设置和文件格式转换
dos2unix filedos.txt fileunix.txt 将一个文本文件的格式从MSDOS转换成UNIX
unix2dos fileunix.txt filedos.txt 将一个文本文件的格式从UNIX转换成MSDOS
recode ..HTML < page.txt > page.html 将一个文本文件转换成html
recode -l | more 显示所有允许的转换格式

17.文件系统分析
badblocks -v /dev/hda1 检查磁盘hda1上的坏磁块
fsck /dev/hda1 修复/检查hda1磁盘上linux文件系统的完整性
fsck.ext2 /dev/hda1 修复/检查hda1磁盘上ext2文件系统的完整性
e2fsck /dev/hda1 修复/检查hda1磁盘上ext2文件系统的完整性
e2fsck -j /dev/hda1 修复/检查hda1磁盘上ext3文件系统的完整性
fsck.ext3 /dev/hda1 修复/检查hda1磁盘上ext3文件系统的完整性
fsck.vfat /dev/hda1 修复/检查hda1磁盘上fat文件系统的完整性
fsck.msdos /dev/hda1 修复/检查hda1磁盘上dos文件系统的完整性
dosfsck /dev/hda1 修复/检查hda1磁盘上dos文件系统的完整性

18.初始化一个文件系统
mkfs /dev/hda1 在hda1分区创建一个文件系统
mke2fs /dev/hda1 在hda1分区创建一个linux ext2的文件系统
mke2fs -j /dev/hda1 在hda1分区创建一个linux ext3(日志型)的文件系统
mkfs -t vfat 32 -F /dev/hda1 创建一个 FAT32 文件系统
fdformat -n /dev/fd0 格式化一个软盘
mkswap /dev/hda3 创建一个swap文件系统

19.SWAP文件系统
mkswap /dev/hda3 创建一个swap文件系统
swapon /dev/hda3 启用一个新的swap文件系统
swapon /dev/hda2 /dev/hdb3 启用两个swap分区

20.备份
dump -0aj -f /tmp/home0.bak /home 制作一个 ‘/home’ 目录的完整备份
dump -1aj -f /tmp/home0.bak /home 制作一个 ‘/home’ 目录的交互式备份
restore -if /tmp/home0.bak 还原一个交互式备份
rsync -rogpav –delete /home /tmp 同步两边的目录
rsync -rogpav -e ssh –delete /home ip_address:/tmp 通过SSH通道rsync
rsync -az -e ssh –delete ip_addr:/home/public /home/local 通过ssh和压缩将一个远程目录同步到本地目录
rsync -az -e ssh –delete /home/local ip_addr:/home/public 通过ssh和压缩将本地目录同步到远程目录
dd bs=1M if=/dev/hda | gzip | ssh user@ip_addr ‘dd of=hda.gz’ 通过ssh在远程主机上执行一次备份本地磁盘的操作
dd if=/dev/sda of=/tmp/file1 备份磁盘内容到一个文件
tar -Puf backup.tar /home/user 执行一次对 ‘/home/user’ 目录的交互式备份操作
( cd /tmp/local/ && tar c . ) | ssh -C user@ip_addr ‘cd /home/share/ && tar x -p’ 通过ssh在远程目录中复制一个目录内容
( tar c /home ) | ssh -C user@ip_addr ‘cd /home/backup-home && tar x -p’ 通过ssh在远程目录中复制一个本地目录
tar cf – . | (cd /tmp/backup ; tar xf – ) 本地将一个目录复制到另一个地方,保留原有权限及链接
find /home/user1 -name ‘*.txt’ | xargs cp -av –target-directory=/home/backup/ –parents 从一个目录查找并复制所有以 ‘.txt’ 结尾的文件到另一个目录
find /var/log -name ‘*.log’ | tar cv –files-from=- | bzip2 > log.tar.bz2 查找所有以 ‘.log’ 结尾的文件并做成一个bzip包
dd if=/dev/hda of=/dev/fd0 bs=512 count=1 做一个将 MBR (Master Boot Record)内容复制到软盘的动作
dd if=/dev/fd0 of=/dev/hda bs=512 count=1 从已经保存到软盘的备份中恢复MBR内容
光盘

cdrecord -v gracetime=2 dev=/dev/cdrom -eject blank=fast -force 清空一个可复写的光盘内容
mkisofs /dev/cdrom > cd.iso 在磁盘上创建一个光盘的iso镜像文件
mkisofs /dev/cdrom | gzip > cd_iso.gz 在磁盘上创建一个压缩了的光盘iso镜像文件
mkisofs -J -allow-leading-dots -R -V “Label CD” -iso-level 4 -o ./cd.iso data_cd 创建一个目录的iso镜像文件
cdrecord -v dev=/dev/cdrom cd.iso 刻录一个ISO镜像文件
gzip -dc cd_iso.gz | cdrecord dev=/dev/cdrom – 刻录一个压缩了的ISO镜像文件
mount -o loop cd.iso /mnt/iso 挂载一个ISO镜像文件
cd-paranoia -B 从一个CD光盘转录音轨到 wav 文件中
cd-paranoia — “-3” 从一个CD光盘转录音轨到 wav 文件中(参数-3)
cdrecord –scanbus 扫描总线以识别scsi通道
dd if=/dev/hdc | md5sum 校验一个设备的md5sum编码,例如一张 CD

22.网络
– (以太网和WIFI无线)
ifconfig eth0 显示一个以太网卡的配置
ifup eth0 启用一个 ‘eth0’ 网络设备
ifdown eth0 禁用一个 ‘eth0’ 网络设备
ifconfig eth0 192.168.1.1 netmask 255.255.255.0 控制IP地址
ifconfig eth0 promisc 设置 ‘eth0’ 成混杂模式以嗅探数据包 (sniffing)
dhclient eth0 以dhcp模式启用 ‘eth0’
route -n show routing table
route add -net 0/0 gw IP_Gateway configura default gateway
route add -net 192.168.0.0 netmask 255.255.0.0 gw 192.168.1.1 configure static route to reach network ‘192.168.0.0/16’
route del 0/0 gw IP_gateway remove static route
echo “1” > /proc/sys/net/ipv4/ip_forward activate ip routing
hostname show hostname of system
host www.example.com lookup hostname to resolve name to ip address and viceversa(1)
nslookup www.example.com lookup hostname to resolve name to ip address and viceversa(2)
ip link show show link status of all interfaces
mii-tool eth0 show link status of ‘eth0’
ethtool eth0 show statistics of network card ‘eth0’
netstat -tup show all active network connections and their PID
netstat -tupl show all network services listening on the system and their PID
tcpdump tcp port 80 show all HTTP traffic
iwlist scan show wireless networks
iwconfig eth1 show configuration of a wireless network card
hostname show hostname
host www.example.com lookup hostname to resolve name to ip address and viceversa
nslookup www.example.com lookup hostname to resolve name to ip address and viceversa
whois www.example.com lookup on Whois database

23.列出目录内容
ls -a:显示所有文件(包括隐藏文件);
ls -l:显示详细信息;
ls -R:递归显示子目录结构;
ls -ld:显示目录和链接信息;
ctrl+r:历史记录中所搜命令(输入命令中的任意一个字符);
Linux中以.开头的文件是隐藏文件;
pwd:显示当前目录

24.查看文件的类型

file:查看文件的类型

25.复制文件目录

1、cp:复制文件和目录 cp源文件(文件夹)目标文件(文件夹)

常用参数:-r:递归复制整个目录树;-v:显示详细信息;

复制文件夹时要在cp命令后面加一个-r参数:

如:cp -r 源文件夹 目标文件夹

2、touch+文件名:当文件不存在的时候,创建相应的文件;当文件存在的时候,修改文件的创建时间。欢迎关注我们,公号终码一生。

功能:生成一个空文件或修改文件的存取/修改的时间记录值。

touch * :将当前下的文件时间修改为系统的当前时间

touch –d 20040210 test:将test文件的日期改为20040210

touch abc :若abc文件存在,则修改为系统的当前时间;若不存在,则生成一个为当前时间的空文件

3、mv 文件 目标目录:移动或重命名文件或目录(如果指定文件名,则可以重命名文件)。可以将文件及目录移到另一目录下,或更改文件及目录的名称。

格式为:mv [参数]<源文件或目录> <目标文件或目录>

mva.txt ../:将a.txt文件移动上层目录

mv a.txt b.txt:将a.txt改名为b.txt

mvdir2 ../:将dir2目录上移一层

4、rm:删除文件;

常用参数:-i:交互式 -r:递归的删除包括目录中的所有内容

5、mkdir +文件夹名称:创建文件夹;

6、rm -r +文件夹名称:删除文件夹(空文件夹和非空文件夹都可删除)

rmdir 文件夹名称:删除文件夹(只能删除空文件夹)

7、mkdir -p dir1/dir2 :在当前目录下创建dir1目录,并在dir1目录下创建dir2目录, 也就是连续创建两个目录(dir1/和dir1/dir2)

8、rmdir –p dir1/dir2:删除dir1下的dir2目录,若dir1目录为空也删除它

9、rm * :删除当前目录下的所有文件

10、-f参数:强迫删除文件 rm –f *.txt:强迫删除所有以后缀名为txt文件

11、-i参数:删除文件时询问

rm –i * :删除当前目录下的所有文件会有如下提示:

rm:backup:is a directory    遇到目录会略过

rm: remove ‘myfiles.txt’ ? Y

删除文件时会询问,可按Y或N键表示允许或拒绝删除文件 

12、-r参数:递归删除(连子目录一同删除,这是一个相当常用的参数)

rm -r test :删除test目录(含test目录下所有文件和子目录)

rm -r *:删除所有文件(含当前目录所有文件、所有子目录和子目录下的文件) 一般在删除目录时r和f一起用,避免麻烦

rm -rf test :强行删除、不加询问

13、grep:功能:在文件中搜索匹配的字符并进行输出

格式:grep[参数] <要找的字串> <要寻找字 串的源文件>

greplinux test.txt:搜索test.txt文件中字符串linux并输出

14、ln命令

功能:在文件和目录之间建立链接

格式:ln [参数] <源文件或目录> <目标文件或目录>

链接分“软链接”和“硬链接”

1.软链接:

ln–s /usr/share/do doc :创建一个链接文件doc,并指向目录/usr/share/do

2.硬链接:

ln /usr/share/test hard:创建一个硬链接文件hard,这时对于test文件对应 的存储区域来说,又多了一个文件指向它

26.系统常用命令

1、显示命令

date:查看或设置当前系统的时间:格式化显示时间:+%Y–%m–%d;

date -s:设置当前系统的时间

hwclock(clock):显示硬件时钟时间(需要管理员权限);

cal:查看日历

格式cal [参数] 月年

cal:显示当月的日历 cal4 2004 :显示2004年4月的日历

cal- y 2003:显示2003年的日历

uptime:查看系统运行时间

2、输出查看命令

echo:显示输入的内容 追加文件echo “liuyazhuang” >> liuyazhuang.txt

cat:显示文件内容,也可以将数个文件合并成一个文件。

格式:格式:cat[参数]<文件名>

cat test.txt:显示test.txt文件内容

cat test.txt | more :逐页显示test.txt文件中的内容

cat test.txt >> test1.txt :将test.txt的内容附加到test1.txt文件之后

cat test.txt test2.txt >readme.txt : 将test.txt和test2.txt文件合并成readme.txt 文件

head:显示文件的头几行(默认10行) -n:指定显示的行数格式:head -n 文件名

tail:显示文件的末尾几行(默认10行)-n:指定显示的行数 -f:追踪显示文件更新 (一般用于查看日志,命令不会退出,而是持续显示新加入的内容)

格式:格式:tail[参数]<文件名>

tail-10 /etc/passwd :显示/etc/passwd/文件的倒数10行内容

tail+10 /etc/passwd :显示/etc/passwd/文件从第10行开始到末尾的内容

more:用于翻页显示文件内容(只能向下翻页)

more命令是一般用于要显示的内容会超过一个画面长度的情况。为了避免画 面显示时瞬间就闪过去,用户可以使用more命令,让画面在显示满一页时暂停,此时可按空格健继续显示下一个画面,或按Q键停止显示。

ls -al |more:以长格形式显示etc目录下的文件列表,显示满一个画面便暂停,可 按空格键继续显示下一画面,或按Q键跳离

less:翻页显示文件内容(带上下翻页)按下上键分页,按q退出、‘

less命令的用法与more命令类似,也可以用来浏览超过一页的文件。所不同 的是less 命令除了可以按空格键向下显示文件外,还可以利用上下键来卷动文件。当要结束浏览时,只要在less命令的提示符“:”下按Q键即可。

ls -al | less:以长格形式列出/etc目录中所有的内容。用户可按上下键浏览或按Q键跳离。

3、查看硬件信息

Ispci:查看PCI设备 -v:查看详细信息

Isusb:查看USB设备 -v:查看详细信息

Ismod:查看加载的模块(驱动)

4、关机、重启

shutdown关闭、重启计算机

shutdown[关机、重启]时间 -h关闭计算机 -r:重启计算机

如:立即关机:shutdown -h now

10分钟后关机:shutdown -h +10

23:30分关机:shutdown -h 23:30

立即重启:shutdown -r now

poweroff:立即关闭计算机

reboot:立即重启计算机

5、归档、压缩

zip:压缩文件 zip liuyazhuang.zip myfile 格式为:“zip 压缩后的zip文件文件名”

unzip:解压文件 unzip liuyazhuang.zip

gzip:压缩文件 gzip 文件名

tar:归档文件

tar -cvf out.tar liuyazhuang 打包一个归档(将文件”liuyazhuang”打包成一个归档)

tar -xvf liuyazhuang.tar 释放一个归档(释放liuyazhuang.tar归档)

tar -cvzf backup.tar.gz/etc

-z参数将归档后的归档文件进行gzip压缩以减少大小。

-c:创建一个新tar文件

-v:显示运行过程的信息

-f:指定文件名

-z:调用gzip压缩命令进行压缩

-t:查看压缩文件的内容

-x:解开tar文件

tar -cvf test.tar *:将所有文件打包成test.tar,扩展名.tar需自行加上

tar -zcvf test.tar.gz *:将所有文件打包成test.tar,再用gzip命令压缩

tar -tf test.tar :查看test.tar文件中包括了哪些文件

tar -xvf test.tar 将test.tar解开

tar -zxvf foo.tar.gz 解压缩

gzip各gunzip命令

gziptest.txt :压缩文件时,不需要任何参数

gizp–l test.txt.gz:显示压缩率

6、查找

locate:快速查找文件、文件夹:locate keyword

此命令需要预先建立数据库,数据库默认每天更新一次,可用updatedb命令手工建立、更新数据库。欢迎关注我们,公号终码一生。

find查找位置查找参数

如:

find . -name *liuyazhuang* 查找当前目录下名称中含有”liuyazhuang”的文件

find / -name *.conf 查找根目录下(整个硬盘)下后缀为.conf的文件

find / -perm 777 查找所有权限是777的文件

find / -type d 返回根目录下所有的目录

find . -name “a*”-exec ls -l {} \;

find功能:用来寻找文件或目录。

格式:find [<路径>] [匹配条件]

find / -name httpd.conf 搜索系统根目录下名为httpd.conf的文件

7、ctrl+c :终止当前的命令

8、who或w命令

功能:查看当前系统中有哪些用户登录

格式:who/w[参数]

9、dmesg命令 功能:显示系统诊断信息、操作系统版本号、物理内存的大小以及其它信息

10、df命令 功能:用于查看文件系统的各个分区的占用情况

11、du命令

功能:查看某个目录中各级子目录所使用的硬盘空间数

格式:du [参数] <目录名>

12、free命令

功能:用于查看系统内存,虚拟内存(交换空间)的大小占用情况

2024 年的最佳 PHP 框架

原创 21CTO
在本文中,我們將預測在 2024 年繼續流行的最佳 PHP 框架。

我們首先將看看PHP框架是什麼,什麼時候該考慮使用PHP框架,以及使用PHP框架的主要優點都是什麼。

我也會介紹最適合初學者的 PHP 框架以及用於 Web 開發的最佳框架。

什麼是PHP框架?

在我們了解使用 PHP 框架的優點以及哪些是最好的 PHP 框架之前,我們先了解什麼是 PHP 框架。

PHP是世界上使用最多的伺服器端程式語言,PHP框架也已經存在了很長時間,並且多年來採取了不同的形式與範式。 它們為從簡單的網站到管理數百萬註冊和日常訪問的大型複雜 Web 應用程式提供動力。

PHP 框架已經使用了幾十年(Phplib,是第一個 PHP 框架,可以追溯到 2000 年之前),它們採取了不同的形式,但它們的主要目的基本上保持不變。 其目的是:透過提供常用函數集以及常用功能庫來幫助 PHP 開發者,並強制使用最佳編碼實踐。

將 PHP 框架想像成一個已經提供了一個正在運行的原始級系統,你可以在其中嵌入自己的程式碼,而無需從頭開始遍歷每個細節。 例如安全性身份驗證? 已經搞好了! 路由? 是的! 依賴注入? 不需要考慮!

透過使用框架,開發者可以大幅減少編寫所需的程式碼量並提高工作效率,同時由於使用程式碼標準和最佳實踐,還可以確保高水準的軟體品質。

探索框架的功能也能幫助我們發展技能的提高,是 PHP 學習的另一種好方法。

什麼時候用 PHP 框架

儘管現在對PHP程式設計師來說,在幾乎每個專案中使用框架似乎都是不費吹灰之力的事兒。 但是在許多情況下,使用PHP框架可能不是最好的主意。 這完全取決於項目。

大多數時候,討論都圍繞著使用什麼框架,而很多時候的討論,應該圍繞著我們是否應該使用一個框架。
框架的主要優勢

雖然在一些極端情況下,使用 PHP 框架並不是解決問題的最佳解決方案,但是,使用框架好處還是要多一些。

首先,我們不必花費時間和精力來規劃應用程式架構、評估各種可用的程式庫並從頭開始實現架構,而是透過使用框架,我們會得到一個功能齊全的模板,而只需要專注於建立特定於 項目的功能。

除此之外,許多 PHP 框架還包括命令列工具,這些工具有助於產生自動程式碼模板,從而進一步加快開發速度。

開發PHP應用程式時最大的問題之一是安全性。 大多數開發者沒有配備創建安全 PHP 應用程式所需的所有工具或技能。 透過使用 PHP 框架,我們使用的解決方案由社群不斷測試、審查和審查。 由於它們中的大多數都是開源的,因此安全問題通常很快就會被注意到並修復。

作為開發者,我們應該牢記技術解決方案和實現方式。 但是當我們在團隊中工作時,情況就會發生變化,因為每個人的解決問題思維將會有所不同。 如果不了解設計決策和程式碼庫的完整文檔,團隊成員會發現程式碼很難使用,有時甚至難以理解應用程式的程式碼邏輯。

使用 PHP 框架可以讓新任開發者更容易開始專案。 即使他們還不熟悉該框架,他們也可能會存取該框架的完整文檔,以及有關如何在 Web 上使用它的影片和教學課程。 這樣開發人員可以專注於開發功能,而不是在整個專案中不斷指導新的團隊成員。

有哪些好PHP框架

PHP框架的世界在過去十年中迅速發展。 就在過去的幾年裡,我們看到了一些穩定的趨勢。

因此,一些框架已成為大多數軟體開發專案的首選。

其實不斷成長的PHP框架清單並非只有五個。 還有一些框架會更適合特定情況,有更快的學習曲線/社群支援等。 在創建這樣的受歡迎清單時,我們會考慮到這些因素,並選擇那些在整體上表現更好的因素。

有了這些警告,你就會知道我們是怎麼排的,然後就來看看 2024 年最值得使用的五個 PHP 框架。

Laravel

以下介紹來自Laravel網站:

Laravel 試圖透過簡化大多數Web 專案中使用的常見任務(例如身份驗證、路由、會話和快取)來消除開發者的一些痛苦……Laravel的目標是在不犧牲應用程式功能的情況下 ,使開發過程令人愉悅。

Laravel 可能是目前最常使用且最受使用者推薦的 PHP 框架。

它於 2011 年由 Taylor Otwell 首次發布,試圖創建一個更高級的CodeIgniter 替代品,當時它尚未提供身份驗證和授權等功能。

Laravel是一個非常廣泛且功能豐富的框架,它遵循MVC模式,並提供開箱即用的功能。
以下的介紹來自Laravel官網:

Laravel 試圖透過簡化大多數Web 專案中使用的常見任務(例如身份驗證、路由、會話和快取)來消除開發的痛苦……Laravel的目標是在不犧牲應用程式功能的情況下,使 開發過程對開發人員來說是令人愉悅的。

Laravel是一個非常廣泛且功能豐富的框架,它遵循MVC模式,並提供開箱即用的功能。 例如:

使用者認證

授權

電子郵件驗證

加密

哈希

密碼重設

在模板方面,Laravel 使用模板引擎 Blade,Eloquent ORM 涵蓋了資料庫互動。 它還使用 Artisan 命令列工具來幫助加快開發速度。

注意:ORM 代表物件關係映射器。 ORM 是一種機制,可以對資料庫物件進行尋址、存取和操作,而無需考慮這些物件與其資料來源的關係。 它本質上是一個黑盒子,用於說明如何與資料庫進行互動。

Laravel 也很容易透過 Composer 或 Homestead、Vagrant box 或 Laravel Valet 等解決方案進行安裝。

規格

發佈時間:2011 年 6 月

目前版本:9,2022 年 1 月發布。

技術要求:PHP >= 8(或使用 Laravel Homestead)

安裝:composer create-project laravel/laravel your-app-name

網址:laravel.com

文件:laravel.com/docs

Symfony

Symfony可以從兩個不同的角度來看。

首先它是一個 PHP 框架,也是用來建立 Web 應用程式的 PHP 元件集合。 由於這種多功能性,Symfony具有高度的可擴展性。 你可以使用整個框架,也可以只選擇幾個適合自己用例的元件。 它可以是簡單的,也可以是複雜的,而Symfony確實是一個偉大的軟體的證據是,大多數其他PHP框架在後台都使用了Symfony組件。

Symfony 使用 Doctrine ORM 進行資料庫交互,並使用 Twig 作為模板引擎。 它還有自己的 CLI 工具來幫助我們開發。

規格

發佈時間:2005年

目前版本:6.1.5,2022 年 5 月發布

技術需求:PHP >= 8

安裝:composer create-project symfony/skeleton:”6.1.*” my_project_directory

網址:symfony.com

文件:Symfony.com/docs

在研究 Laravel 和 Symfony 時要考慮的另一件事是,兩者都有大量的開發人員社群積極使用它們並為其開發。 兩者的文檔都非常友好且內容廣泛。

CakePHP
CakePHP 背後的想法是建立一個專注於快速開發的 Web 開發框架,使建立 Web 應用程式更簡單、更快捷,並且只需很少的程式碼。 這個想法是使用約定而不是配置來實現快速工作。 這表示並沒有 XML 或 YAML 檔案。

CakePHP 有其內建的 ORM,在模板方面,它使用自己的.ctp檔案格式,使用替代的 PHP 語法來控制其結構和輸出。

就像其他框架一樣,CakePHP 實作了安全功能,例如加密、密碼雜湊、保護表單資料和 CSRF 保護。

儘管它的社群不像 Laravel 那樣龐大和充滿活力,但仍有許多資源和活動可供 CakePHP 開發者使用。

規格

發佈時間:2005年

目前版本:4.4,2022 年 8 月發布

技術需求:PHP >= 7.4

安裝:composer create-project –prefer-dist cakephp/app:~4.0 my_app_name

網址:cakephp.org

CodeIgniter

如同 CakePHP 一樣,CodeIgniter 被發明為一個快速開發的 MVC 框架,具有最少的配置。 但它的創造者將其提升到了一個新的水平。

CodeIgniter 的佔用空間非常小(下載量為 1.2MB),這意味著它幾乎沒有臃腫多餘的程式碼,而且速度也非常快。

儘管 CodeIgniter 沒有與 ORM 捆綁在一起,但它有一個功能齊全且非常快速的抽象資料庫類,它同時支援傳統結構和查詢建構器模式。 模板也是一樣:儘管我們可以使用外部模板引擎或普通的 PHP,但 CodeIgniter 也提供有一個可以使用的類別:Template。

規格

發佈時間:2006 年

目前版本:4.1,2022 年 2 月發布

技術需求:PHP >= 7.4

安裝:composer create-project codeigniter4/appstarter your-app-name

網址:codeigniter.com

文件:CodeIgniter 文檔

FuelPHP

FuelPHP 是此列表中最年輕的框架。 它的官網這樣描述:

Fuel PHP 框架是一個快速、簡單、靈活的 PHP 5.x框架,誕生於其他框架的最佳理念,是一個全新的開始!

FuelPHP 充滿了「新」的概念和範式,例如使用 HMVC(分層模型視圖控制器)而不僅僅是 MVC。 HMVC 提供更好的程式碼組織、更大的模組化、更多的可擴充性,並鼓勵程式碼重複使用。

FuelPHP 提供了自己的 ORM 和命令列工具,並擁有一個小而熱情的社群。 儘管 FuelPHP 是所展示的框架中最年輕的,但它絕對是一個值得考慮的選擇。

規格

發佈時間:2014 年

目前版本:1.9,2021 年 12 月發布

技術需求:PHP >= 5.3

安裝:composer create-project fuel/fuel –prefer-dist .

網址:fuelphp.com

文件:fuelphp.com/docs

結論

在完成本文之前,我想先給大家一些在使用 PHP 框架時要記住的一些特點:

沒有適合所有項目的框架。 只有當它能夠解決問題時,它就是最好的。

在選擇框架時,在做出決定之前,請確保框架能夠得到支持,定期更新,並且背後有一個良好的用戶社群。

一直實踐! 請確保你感到舒適,並喜歡自己選擇的框架。 如果你對使用「最好的」框架感到有一丟丟痛苦,那麼使用它就沒什麼意義。

永遠不要停止學習! 你對框架的實踐,還有踢輪胎的次數越多,你對科技的了解就越多。

Linux 系統之 OOM 解析

Luga Lee twt企业IT社区
【摘要】基於 VM 環境所部署的 Spring Boot 應用服務,運行過程中內存利用往往達到 90% 甚至以上,本文嘗試對此類在實際業務場景中內存表現的活動現象及背後原因進行分析。
【作者】李傑,專注於Java虛擬機器技術、雲端原生技術領域的探索與研究,個人大眾號「架構驛站」。

在實際的業務場景中,有沒有發現這樣一種場景:基於VM 環境上面所部署的Spring Boot 應用服務,往往在運行過程中將內存利用的足夠“猥瑣”,常常達到90% 甚至以上,此時 ,很大一部分夥伴就開始「叫」了。 曰:領導,記憶不夠了,趕緊擴容! ! ! (此刻,有大佬肯定在想:擴你妹,整天搞這些沒用的~)

那個傻子是不是瘋了? 不知道身為所謂的「技術」人員,大家是如何面對的,如何解決? 本文將聚焦於 Linux 記憶體結構、記憶體分析以及 OOM killer 等 3 個面向以及筆者多年的實務經驗總結來進行解析。

記憶體結構

從宏觀角度而言,記憶體管理系統是作業系統最重要的部分之一。 在記憶體管理的系統呼叫方式,事實上,基於 POSIX 並沒有給記憶體管理指定任何的系統呼叫。 然而,Linux 卻有自己的記憶體系統調用,主要係統調用如下:

系統呼叫 描述
s = brk(addr) 改變資料段大小
a = mmap(addr,len,prot,flags,fd,offset) 進行映射
s = unmap(addr,len) 取消映射
1、brk 透過給出超過資料段之外的第一個位元組位址來指定資料段的大小。 如果新的值要比原來的大,那麼資料區就會變得越來越大,反之會越來越小。

2、mmap 和 unmap 系統呼叫會控制映射檔。 mmp 的第一個參數 addr 決定了檔案對映的位址。 它必須是頁面大小的倍數。 如果參數是 0,系統會指派位址並傳回 a。 第二個參數是長度,它告訴了需要映射多少位元組。 它也是頁面大小的倍數。 prot 決定了映射檔的保護位,保護位可以標記為 可讀、可寫、可執行或這些的結合。 第四個參數 flags 能夠控製檔案是私有的還是可讀的以及 addr 是必須的還是只是進行提示。 第五個參數 fd 是要對應的檔案描述子。 只有開啟的檔案是可以被映射的,因此如果想要進行檔案映射,必須開啟檔案;最後一個參數 offset 會指示檔案從何時開始,不一定每次都要從零開始。

針對 Linux 記憶體管理及實現,其實其涉及的面較廣,較為複雜,從電腦早期開始,我們在實際的業務場景中所使用的記憶體往往都要比系統中實際存在的記憶體多。 為此,記憶體分配策略克服了這個限制,而其中最有名的就是引入: 虛擬記憶體(Virtual Memory)。 透過在多個競爭的進程之間共享虛擬內存,虛擬內存得以讓系統有更多的內存,以方便維護系統資源的分配。 先來張總概覽圖,具體如下圖所示:

Linux 內存,通常被認為指的是“物理內存”,然而,只有內核才可以直接訪問物理內存,進程需要訪問內存,Linux 內核則需要為每個進程提供一個獨立的虛擬地址空間,訪問的是 虛擬記憶體。

通常而言,虛擬記憶體空間的內部被劃分為核心空間和使用者空間:

1.進程在用戶態,只能存取用戶空間內存

2.行程進入內核態才能存取核心空間內存

3.每個行程都包含內核空間,但這些內核空間都關聯相同的實體內存

而針對記憶體映射,其主要將虛擬記憶體位址映射到實體記憶體位址,為了完成記憶體映射。 核心每個進程都維護了一張頁表,記錄虛擬位址和實體位址的映射關係,頁表實際儲存在CPU 的記憶體管理單元 MMU,這樣處理器就可以直接透過硬體找出要存取的記憶體。

再來一張內核線形位址空間佈局圖,具體可參考如下「硬核」示意圖:

針對上述結構圖,簡單描述如下:

1.核心直接映射空間 PAGE_OFFSET~VMALLOC_START,kmalloc和__get_free_page()分配的是這裡的頁面。 二者是藉助 Slab分配器,直接分配實體頁再轉換為邏輯位址(實體位址連續)。 適合分配小段記憶體。 此區域 包含了核心鏡像、實體頁框表mem_map 等資源。

2.核心動態映射空間 VMALLOC_START~VMALLOC_END,被 vmalloc 用到,可表示的空間大。

3.核心永久映射空間 PKMAP_BASE ~ FIXADDR_START,kmap

4.核心臨時映射空間 FIXADDR_START~FIXADDR_TOP,kmap_atomic

記憶體分析

針對記憶體分析部分,其實可利用的手段或策略較多,基於不同段位的水平高低之分,通常,我們可以藉助Top、Free 指令以及Vmstat 指令進行追蹤及觀測記憶體的動態活動變化趨勢,以即時了解 目前作業系統的資源水位,具體如下所示:

[administrator@JavaLangOutOfMemory ~ ] %top
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 128032 7996 5556 S 80.0 80.4 0:01.03 java
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
基於上述輸出結果,簡單解析如下:

1、VIRI: 虛擬內存,包括了進程的代碼段、數據段、共享內存、已經申請的堆內存和已經換出的內存等,已經申請的內存,即使還未分配物理內存,也算做虛擬內存

2、RSS: 常駐內存,是進程實際使用的實體內存,不包括 Swap 和共享內存

3、SHR: 共享內存,包括與其他進程共同使用的真實共享內存,包括加載的動態鏈接庫以及程序的代碼段

4、%MEM: 進程使用實體記憶體佔系統記憶體的百分比

[administrator@JavaLangOutOfMemory ~ ] %free
total used free shared buff/cache available
Mem: 2031744 98176 1826192 8784 107376 1800144
Swap: 2097148 0 2097148
此命令列輸出內容較為簡單:主要列印已使用、剩餘、可用、共享記憶體以及快取等資訊。 部分參數釋義如下圖所示:

1、Shared: 共享記憶體, 共享記憶體是透過 Tmpfs 實現的,它的大小就是 Tmpfs 使用的記憶體大小。

2、Available: 可用內存,是新進程可以使用的最大內存,包括剩餘內存和還未使用的內存。

3、Buffer/Cache: 快取包括兩部分,一部分是磁碟讀取檔案的頁緩存,用來緩存從磁碟讀取的數據,加速以後再次存取速度,另一部分是Slab 分配的可回收快取;緩衝區是 對原始磁碟的暫存,用來快取將要寫入磁碟的數據,統一最佳化磁碟寫入。

[administrator@JavaLangOutOfMemory ~ ] %vmstat 1 1
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 1815348 2108 111872 0 0 1 0 11 11 0 0 100 0 0
基於上述輸出結果,簡單解析如下:

1、si: 換入,每秒從磁碟讀入虛擬記憶體的大小,若此值長時間持續大於0,表示實體記憶體不夠或記憶體洩漏,需要定位問題。

2、so: 換出,每秒鐘從記憶體寫入磁碟的大小,若此值長時間持續大於0,表示實體記憶體不夠用,就需要排查記憶體問題。

OOM Killer

通常有這樣的一種場景:若一台VM (虛擬機)上部署多個應用服務,此處,暫以Spring Boot 微服務為例,在某種特殊的時刻,例如:業務促銷、壓力測試或 當某一個聯機負載節點或因網路抖動而掛掉時,此台VM 上的服務突然在毫無徵兆的情況下,突然被「掛掉」。

同時,我們開始蒐集相關線索,以便能夠快速定位到問題原因,將「罪魁禍首」逮捕歸案。

那麼,為什麼會出現這種問題呢? 它是如何產生的? OOM,全稱為 “Out Of Memory”,即 記憶體溢位。 OOM Killer 是 Linux 自我保護的方式,防止記憶體不足時出現嚴重問題。

Linux 核心所採用的此種機制會不時監控所運行中佔用記憶體過大的進程,尤其針對在某一種瞬間場景下佔用記憶體較快的進程,為了防止作業系統記憶體耗盡而不得不自動將此 進程Kill 掉。 通常,系統核心偵測到系統記憶體不足時,篩選並終止某個行程的過程可以參考核心原始碼:linux/mm/oom_kill.c,當系統記憶體不足的時候,out_of_memory()被觸發,然後呼叫select_bad_process( ) 選擇一個”bad” 進程殺掉。 如何判斷和選擇一個」bad 進程呢?Linux 作業系統選擇」bad」進程是透過呼叫 oom_badness(),挑選的演算法和想法都很簡單很樸實:最 bad 的那個進程就是那個最佔用記憶體的進程。

OOM Killer 原始碼解析

OOM killer的核心函數是 out_of_memory(), 執行流程如下:

1.呼叫 check_panic_on_oom() 檢查是否允許執行核心恐慌,假如允許,需要重新啟動系統。

2.若定義了 /proc/sys/vm/oom_kill_allocating_task 即允許 Kill 掉目前正在申請分配物理記憶體的程序,那麼殺死目前程序。

3.呼叫 select_bad_process,選擇 badness score 最高的進程。

4、呼叫 oom_kill_process, 殺死選擇的進程。

我們透過分析 Badness Score 的計算函數來理解 OOM Killer 是如何選擇需要被 Kill 掉的進程,具體原始碼可參考如下所示:

unsigned long oom_badness(struct task_struct *p, struct mem_cgroup *memcg,
const nodemask_t *nodemask, unsigned long totalpages)
{
long points;
long adj;

/* 假如该进程不能被kill, 则分数返回0. */
if (oom_unkillable_task(p, memcg, nodemask))
return 0;

p = find_lock_task_mm(p);
if (!p)
return 0;

/* 获取该进程的 oom_score_adj, 这个是用户为进程设置的 badness score
* 调整值,假如这个值为-1000或者进程被标记为不可被kill,或者进程处于
* vfork()过程,badness score返回0. */
adj = (long)p->signal->oom_score_adj;
if (adj == OOM_SCORE_ADJ_MIN ||
test_bit(MMF_OOM_SKIP, &p->mm->flags) ||
in_vfork(p)) {
task_unlock(p);
return 0;
}

/* badness score分数 = 物理内存页数 + 交换区页数 + 页表Page Table数量. */
points = get_mm_rss(p->mm) + get_mm_counter(p->mm, MM_SWAPENTS) +
mm_pgtables_bytes(p->mm) / PAGE_SIZE;
task_unlock(p);

/* 利用以下公式对 badness score 值进行调整. */
adj *= totalpages / 1000;
points += adj;

/* 返回 badness score, 假如等于0, 则返回 1. */
return points > 0 ? points : 1;
}
透過對 Badness Score 計算函數的分析,我們可以發現 OOM Killer 是基於 RSS 即常駐的實體記憶體來選擇進程進行 Kill 操作, 從而釋放相關記憶體以進行系統自我保護。 有關 OOM Killer 相關配置、查看及分析將於後續文章給出,大家到時留意查看。

綜上所述,本篇文章主要透過基於對Linux 記憶體結構、分析及OOM Killer 3個核心維度,從主動及被動場景等2 面向對Linux 作業系統記憶體的剖析,以探討在實際的業務場景中, 記憶體表現的相關活動及經驗認知。