不用装任何图形界面,一台最小化安装的服务器和一台满配的桌面发行版,摆在你面前的是完全不同的命令世界。很多人初学Linux时都有过这种经历:教程里写free -m能看内存,结果自己在一台CentOS 7上执行,输出格式和网上截图对不上;换到Ubuntu 22.04,lscpu还在,但到了某些精简版Alpine上,连lspci都没安装。系统信息查看这组命令,看似基础,实际上跨发行版的差异比想象中大得多。本文我把常用的系统信息查看命令从原理到实际输出逐一拆开讲清楚,并给出跨发行版适配的完整思路,适合刚入门想系统梳理命令体系的新手,也适合需要在多发行版之间切换维护的运维朋友参考。
1. 先搞懂原理:为什么“同样都是Linux”命令表现却不一样
很多教程把Linux命令当成一个固定不变的工具集来讲,但真正上手多台不同发行版的机器后就会发现,同一个命令在不同系统上输出格式不一样,甚至命令本身都不存在。这不是Linux“不标准”,而是我们没有搞清楚命令背后分了哪几层。
1.1 内核、发行版、工具集这三层关系要理清
Linux系统从底层到上层大致分三层:内核(Kernel)、发行版(Distribution)、用户态工具集(Userland Tools)。内核负责管理硬件资源,对外暴露接口;发行版负责把内核、系统库、软件包管理器、默认工具集打成一个可安装的整体;用户态工具集则是我们平时敲的命令,比如free、df这些。
系统信息查看命令大部分是通过读取内核暴露的虚拟文件系统来获取数据的,其中两个目录最核心:/proc和/sys。/proc是进程信息虚拟文件系统,/sys是设备与内核对象信息虚拟文件系统。比如/proc/cpuinfo保存了CPU详细信息,/proc/meminfo保存了内存使用情况。
free命令本质上就是解析/proc/meminfo之后做一次单位换算和格式化输出;lscpu命令则是解析/proc/cpuinfo和/sys/devices/system/cpu/下的信息后重新组装为一个更易读的视图。所以,工具只是外壳,数据源头是内核虚拟文件。
1.2 工具集不同,输出自然不同
不同发行版打包的工具集有差异,这种差异主要来自以下几个方面:
- procps-ng 版本差异:
free、ps、top这些命令属于procps包(新版本叫procps-ng)。不同版本对同一字段的展示方式不同,最典型的就是free命令的显示单位从KB变成了可读性更强的自动单位,而且新增了available这一列。 - util-linux 版本差异:
lsblk、blkid、lscpu、findmnt这些命令属于util-linux包,很多系统信息命令都集中在这个包里。跨版本时输出可能增加新列或调整字段名。 - 额外工具是否预装:
lspci属于pciutils包,lsusb属于usbutils包,dmidecode属于dmidecode包。最小化安装的服务器可能一个都没有,这跟发行版没关系,纯粹是安装时没选对应的软件包组。 - systemd 生态的融入程度:使用systemd作为init系统的发行版多出了
hostnamectl、journalctl、timedatectl等命令,这些命令在CentOS 6、Alpine这类非systemd环境下是不存在的。
理解这层原理之后,跨发行版适配的思路就清晰了:优先使用不依赖额外安装的底层虚拟文件,其次再考虑各种封装好的工具命令。内核虚拟文件的路径在所有Linux发行版上几乎一致,这是最稳定的兼容层。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 内核与发行版信息查看:从uname参数到os-release标准
拿到一台陌生Linux服务器,第一件事就是确认内核版本和发行版版本。这一步做对了,后续排查问题的方向才不会跑偏。
2.1 uname命令:被低估的参数细节
uname是最基础的内核信息查看命令,几乎存在于所有Linux环境(包括BusyBox)。不带参数执行uname只输出内核名称Linux,实际使用时需要带参数组合。
最常用的执行方式是:
bash复制uname -a
在CentOS 7.9上的输出大致长这样:
code复制Linux vm-01 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
逐个字段拆开解释:
Linux:内核名称。vm-01:主机名(hostname)。3.10.0-1160.el7.x86_64:内核版本号。其中3.10.0是主版本号,1160是构建批次,el7表示这是为RHEL/CentOS 7编译的内核。#1 SMP Mon Oct 19 16:18:59 UTC 2020:编译序号与编译时间,SMP表示支持对称多处理器。- 最后的
x86_64 x86_64 x86_64:分别是硬件平台、处理器类型、操作系统架构。 GNU/Linux:操作系统名称。
如果只想取内核版本做脚本判断,用uname -r更精确:
bash复制[root@vm-01 ~]# uname -r
3.10.0-1160.el7.x86_64
判断架构用uname -m:
bash复制[root@vm-01 ~]# uname -m
x86_64
注意uname -m在32位系统上输出i686或i386,在ARM 64位(aarch64)上输出aarch64,下载二进制安装包时判断架构基本都靠它。uname -n获取主机名,等价于hostname命令,但hostname在某些容器环境下输出可能与uname -n不一致,脚本里建议优先用uname -n。
2.2 /etc/os-release:发行版信息的统一标准
早期判断发行版靠的是查看/etc/redhat-release、/etc/SuSE-release这些各自定义的杂散文件,每家的文件路径和格式都不一样。后来systemd的普及推动了/etc/os-release成为事实标准,几乎所有现代发行版都提供这个文件。
直接查看内容:
bash复制cat /etc/os-release
Ubuntu 22.04上的输出:
code复制PRETTY_NAME="Ubuntu 22.04.3 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.3 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
CentOS 7.9上的输出:
code复制NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
脚本里判断发行版,最推荐的方式是source这个文件然后读取变量:
bash复制source /etc/os-release
echo "$ID $VERSION_ID"
这样取到的ID就是机器可读的发行版标识(如centos、ubuntu、debian、alpine),VERSION_ID是主版本号。用这种方式的健壮性远高于grep关键字匹配。
2.3 hostnamectl与systemd环境
在systemd发行版上,hostnamectl不仅显示主机名,还一次性汇总了操作系统、内核、架构信息:
bash复制hostnamectl
输出格式:
code复制 Static hostname: vm-01
Icon name: computer-vm
Chassis: vm
Machine ID: 3f9f8f0a8b7c4d5e9f0a1b2c3d4e5f6a
Boot ID: 8f8e8e5a2f3b4c5d9e0f1a2b3c4d5e6f
Operating System: Ubuntu 22.04.3 LTS
Kernel: Linux 5.15.0-91-generic
Architecture: x86-64
hostnamectl在CentOS 7(systemd环境)和CentOS 6(SysV init环境)上的行为完全不同,CentOS 6上根本没有这个命令。所以判断一个发行版是否支持hostnamectl,本质是判断它是否使用systemd。对于非systemd环境,可以回退到uname加/etc/os-release的组合方案。
实际操作中,判断发行版信息的推荐顺序是:先看/etc/os-release是否存在,存在则直接source读取;不存在(比如某些精简容器)则uname -a和cat /etc/issue作为兜底。/etc/issue是登录提示文件,通常包含发行版名称,但内容可被用户自定义,参考价值低于os-release。
3. CPU、内存、磁盘信息三板斧:命令输出字段逐个拆解
CPU、内存、磁盘是日常排查故障时最常查看的三个维度。这里的核心思路很简单:优先用封装好的命令(lscpu、free、lsblk),这些命令在绝大多数发行版上都有;一旦发现命令缺失,立刻切换到/proc下的原始文件,保证在任何环境都能拿到数据。
3.1 lscpu:CPU拓扑信息的最佳入口
lscpu命令从/proc/cpuinfo和sysfs中收集信息,整理成一个表格化输出。和直接看/proc/cpuinfo相比,lscpu把“物理CPU颗数”“每颗核心数”“线程数”“NUMA节点”这些关键信息归纳得更为清晰。
在一台2路物理服务器(每路8核心16线程)上的典型输出:
bash复制lscpu
code复制Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
Address sizes: 46 bits physical, 48 bits virtual
CPU(s): 32
On-line CPU(s) list: 0-31
Thread(s) per core: 2
Core(s) per socket: 8
Socket(s): 2
NUMA node(s): 4
Vendor ID: GenuineIntel
CPU family: 6
Model: 85
Model name: Intel(R) Xeon(R) Gold 6248 CPU @ 2.50GHz
Stepping: 7
CPU MHz: 2400.000
CPU max MHz: 3900.0000
CPU min MHz: 1200.0000
BogoMIPS: 5000.00
Virtualization features:
Virtualization: VT-x
Caches (sum of all):
L1d: 1 MiB
L1i: 1 MiB
L2: 32 MiB
L3: 44 MiB
NUMA node0 CPU(s): 0-7,16-23
NUMA node1 CPU(s): 8-15,24-31
几个关键字段要会读:
CPU(s):逻辑CPU总数,等于物理CPU颗数乘以每颗核心数乘以每核心线程数。Thread(s) per core:超线程数,为2表示开了超线程,为1则没有。Core(s) per socket:每颗物理CPU的核心数。Socket(s):物理CPU插槽数量。NUMA node(s):NUMA节点数,大内存服务器上常见2个或4个。Virtualization:是否支持硬件虚拟化,KVM部署前通常要先看一眼这个字段。
lscpu支持以JSON格式输出,lscpu --json在部分新版本上可用,适合脚本解析。但老版本(比如CentOS 7自带版本)不支持这个参数,如果脚本需要兼容老系统,建议还是直接解析/proc/cpuinfo。
/proc/cpuinfo的经典读取方式:
bash复制# 查看逻辑CPU个数
grep -c processor /proc/cpuinfo
# 查看物理CPU颗数
grep "physical id" /proc/cpuinfo | sort -u | wc -l
# 查看CPU型号
grep "model name" /proc/cpuinfo | head -1
注意,在ARM架构(如鲲鹏、飞腾)上,/proc/cpuinfo字段和x86架构有区别,没有physical id,processor字段的含义也略有不同。ARM上建议结合lscpu读取,尽量不要写死解析/proc/cpuinfo的脚本。
3.2 free:内存查看命令的版本迁移史
free命令几乎每个管理员都敲过,但不同发行版上的输出格式差异极大,这里专门展开讲。
在CentOS 6上执行free -m:
code复制 total used free shared buffers cached
Mem: 7811 4966 2845 43 266 2066
-/+ buffers/cache: 2633 5178
Swap: 4095 0 4095
在CentOS 7.9上执行free -m:
code复制 total used free shared buff/cache available
Mem: 7811 2413 3103 43 2294 5064
Swap: 4095 0 4095
在Ubuntu 22.04上执行free -h:
code复制 total used free shared buff/cache available
Mem: 15Gi 2.1Gi 8.3Gi 210Mi 5.1Gi 12Gi
Swap: 2.0Gi 0B 2.0Gi
差异点一目了然:
- CentOS 6的版本有两行Mem,第二行是“-/+ buffers/cache”修正后的真实占用;CentOS 7之后取消了这个展示方式,把buffers和cached合并为
buff/cache列,并新增了available列。 available列估算的是“在不触发swap的情况下,可供新进程使用的内存大小”,这是判断系统内存是否紧张的最重要指标。- CentOS 7默认单位是KB(不带单位时不加
-m),加-m显示MB;Ubuntu 22.04的procps-ng版本较新,free -h能自动选择可读单位。 - 老版本
free没有available列,与新版本对比时容易误判内存压力。
手动计算可用内存的兼容方案:如果系统没有available字段(比如CentOS 6),可以近似用free + buffers + cached来估算。更精确的值从/proc/meminfo里取MemAvailable字段,这个字段在较新内核(3.14+)中都有,比解析free输出更稳定。
脚本推荐使用方式,直接从/proc/meminfo读取:
bash复制grep MemTotal /proc/meminfo
grep MemAvailable /proc/meminfo
/proc/meminfo的单位固定是KB,这在所有Linux发行版上一致。解析这个文件做监控脚本,可以避免free命令输出格式变化带来的兼容问题。
3.3 df与lsblk:磁盘信息的两种视角
磁盘信息看两个维度:文件系统空间使用情况,以及块设备层次结构。
查看文件系统空间:
bash复制df -hT
-h表示人类可读单位,-T显示文件系统类型。输出示例:
code复制Filesystem Type Size Used Avail Use% Mounted on
/dev/vda1 ext4 40G 12G 26G 32% /
tmpfs tmpfs 7.8G 0 7.8G 0% /dev/shm
/dev/vdb1 xfs 100G 33G 68G 33% /data
df中需要注意的关键信息:Avail是普通用户实际可用的空间,root用户有5%的保留空间(ext4/xfs默认保留),所以root看到的空间大小可能和普通用户不一致。文件系统类型(xfs、ext4、btrfs)决定了后续扩容、修复工具的选择,df -T能一次看到。
查看块设备结构:
bash复制lsblk
输出示例:
code复制NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 253:0 0 40G 0 disk
└─vda1 253:1 0 40G 0 part /
vdb 253:16 0 100G 0 disk
└─vdb1 253:17 0 100G 0 part /data
lsblk以树状结构展示磁盘、分区、LVM逻辑卷、加密卷之间的层级关系。从输出可以直观看到:/dev/vda整块盘只有一个分区vda1挂载在根目录,/dev/vdb的vdb1挂载在/data。
配合lsblk -f可以额外看到文件系统类型和UUID:
bash复制lsblk -f
code复制NAME FSTYPE LABEL UUID MOUNTPOINT
vda
└─vda1 ext4 a1b2c3d4-... /
vdb
└─vdb1 xfs 5e6f7a8b-... /data
获取UUID的另一种方式是blkid命令:
bash复制blkid /dev/vda1
code复制/dev/vda1: UUID="a1b2c3d4-..." TYPE="ext4"
blkid在脚本里经常用来做“按UUID查找设备”的操作,比如修改/etc/fstab之前先确认UUID是否正确。但注意,blkid在一些老系统或者精简容器上可能未安装,兜底方案是读/dev/disk/by-uuid/目录下的符号链接:
bash复制ls -l /dev/disk/by-uuid/
另外还要提一下iostat——它是sysstat包里的命令,用于查看磁盘IO性能指标(iostat -x 1查看每秒IO使用率、await、util等),最小化安装一般不带。如果系统没装sysstat,临时查看磁盘IO可以看/proc/diskstats,但解析成本较高,建议直接安装sysstat。
3.4 内存、CPU、磁盘三板斧的跨发行版搭配策略
把上面的知识点串成一个“三板斧”组合,适配逻辑可以总结成一张表格:
| 查看目标 | 优先命令 | 命令缺失时的兜底方案 | 兜底数据源 |
|---|---|---|---|
| CPU型号与核数 | lscpu |
grep "model name" /proc/cpuinfo |
/proc/cpuinfo |
| 内存总量与可用 | free -h |
grep MemTotal /proc/meminfo |
/proc/meminfo |
| 磁盘空间 | df -hT |
cat /proc/mounts |
/proc/mounts |
| 块设备结构 | lsblk |
fdisk -l |
/sys/block/ |
| 文件系统UUID | blkid |
ls -l /dev/disk/by-uuid/ |
/dev/disk/by-uuid/ |
用这套组合,哪怕手头是一台只有BusyBox的救援系统,也能完成基本的系统信息采集。
4. 外设与硬件信息:lspci、lsusb、dmidecode的安装与细节
CPU、内存、磁盘之外,查看PCI设备、USB设备、硬件固件信息也是排查硬件故障的必要手段。这组命令在桌面发行版上基本预装,但服务器最小化安装往往没有,需要手动安装。
4.1 lspci:PCI设备树查看
lspci列出所有PCI总线上的设备,包括显卡、网卡、RAID卡、NVMe SSD等。执行lspci输出示例:
bash复制lspci
code复制00:00.0 Host bridge: Intel Corporation Sky Lake-E DM3 Registers
00:1f.6 Ethernet controller: Intel Corporation Ethernet Connection X722 for 10GbE SFP+
01:00.0 RAID bus controller: Broadcom / LSI MegaRAID SAS-3008
设备编号00:00.0格式是“总线号:设备号.功能号”。排查网卡对应哪个PCI设备时,加-v或-vv查看更详细信息,包括内核驱动名、IRQ、内存地址等:
bash复制lspci -vv -s 00:1f.6
-s参数指定查看某个PCI地址。输出中重点看Kernel driver in use字段,这一行显示了内核正在使用哪个驱动。
查看网卡、显卡等设备对应的内核模块或PCI ID信息,用lspci -nnk也很方便:
bash复制lspci -nnk | grep -i ethernet -A 3
如果系统提示lspci: command not found,在CentOS/RHEL系执行:
bash复制yum install -y pciutils
在Ubuntu/Debian系执行:
bash复制apt install -y pciutils
Alpine等小发行版可以用apk add pciutils。
4.2 lsusb:USB设备列表
lsusb在服务器上主要用于排查USB键盘、USB转串口、USB HDD等外接设备。直接执行输出:
bash复制lsusb
code复制Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 046d:c31c Logitech, Inc. Keyboard K120
对应软件包是usbutils,安装方式:
bash复制# CentOS/RHEL
yum install -y usbutils
# Ubuntu/Debian
apt install -y usbutils
需要确认某个USB设备是否被识别时,看ID后面的厂商号:产品号(如046d:c31c),通过lsusb -v -d 046d:c31c可以查看设备描述符。设备拔出再插入时编号会变化,但USB口和总线位置不变,结合dmesg | tail能追踪设备枚举过程。
4.3 dmidecode:硬件身份信息读取
dmidecode读取的是DMI(Desktop Management Interface)表,包含BIOS信息、主板型号、内存插槽、序列号等底层硬件信息。这个命令需要root权限:
bash复制dmidecode -t system
输出包含厂商、产品名称、序列号:
code复制System Information
Manufacturer: Dell Inc.
Product Name: PowerEdge R740
Serial Number: XXXX
查看内存插槽信息:
bash复制dmidecode -t memory | less
可以确认内存条是DDR4还是DDR5、频率多少、插在哪个槽位、是否启用ECC。服务器扩容之前,用dmidecode -t memory核对当前内存条规格是最稳妥的做法。
dmidecode还有一些限制要注意:虚拟机上执行时读到的是虚拟硬件信息(如QEMU/KVM),没有太多参考价值;物理机上如果BIOS提供的SMBIOS表不全,部分字段可能显示Not Specified。软件包名就叫dmidecode,各发行版直接安装即可。
4.4 硬件信息查看命令的横向对比
| 命令 | 所属软件包 | 是否需要root | 主要用途 | 最小化安装是否预装 |
|---|---|---|---|---|
lspci |
pciutils | 不需要 | PCI设备列表 | 通常不装 |
lsusb |
usbutils | 不需要 | USB设备列表 | 通常不装 |
lspcmcia |
pcmciautils | 不需要 | PCMCIA设备 | 极少用 |
dmidecode |
dmidecode | 需要 | 主板/BIOS/内存条信息 | 通常不装 |
lshw |
lshw | 建议root | 全面硬件信息汇总 | 通常不装 |
hwinfo |
hwinfo | 建议root | OpenSUSE系常用 | 不装 |
lshw能一次性列出CPU、内存、磁盘、网络、显示等全部硬件信息,比较适合整体摸底,但输出内容较长,实际排查单项问题时不如定向使用lspci、dmidecode来得快。在需要把硬件订阅上报给资产管理平台时,lshw -json输出结构化数据会更方便。
我在实际运维中已经踩过好几次“不带lspci就上服务器”的坑了。新装的CentOS最小化系统,网卡名片识别不出来,网卡灯又不亮,第一反应就是lspci | grep -i ethernet,结果提示命令不存在。后来我养成了习惯,新机器到手先执行一轮yum install -y pciutils usbutils dmidecode(Debian系对应apt install),把基础排查工具补上,再开始后续部署。
5. 内核日志与运行状态:dmesg、journalctl的适配逻辑
系统运行状态的信息不只来自命令本身,还来自内核日志。内核日志的查看方式在不同init系统下经历了明显变化,这也是跨发行版适配中最容易搞混的一个点。
5.1 dmesg:内核环形缓冲区的读取
dmesg直接读取内核环形缓冲区(kernel ring buffer),里面保存了从开机到当前的内核日志,包括硬件识别、驱动加载、磁盘报错、OOM事件等。排查硬件问题时,dmesg基本上是第一手资料。
执行:
bash复制dmesg | tail -30
查看最近30条内核日志,典型输出包含硬件初始化信息:
code复制[ 0.000000] Linux version 5.15.0-91-generic
[ 0.864239] ACPI: Intel ACPI FULL
[ 2.351922] megaraid_sas 0000:01:00.0: FW now in Ready state
[ 4.657110] XFS (vda1): Mounting V5 Filesystem
但在较新的系统上,直接执行dmesg可能提示权限不足:
code复制dmesg: read kernel buffer failed: Operation not permitted
这是因为内核从4.x开始收紧了dmesg权限,普通用户不再允许读取内核环形缓冲区。解决办法有两个:以root用户执行,或者允许当前用户读取(sysctl kernel.dmesg_restrict=0)。大多数发行版默认dmesg_restrict=1,所以建议直接加sudo:
bash复制sudo dmesg | tail -30
查看与硬件错误相关的日志,配合grep过滤更高效:
bash复制sudo dmesg | grep -i error
sudo dmesg | grep -i "Out of memory"
sudo dmesg | grep -i usb | tail -20
5.2 journalctl:systemd时代的日志中心
systemd将内核日志和应用日志统一集中管理。journalctl不仅能看到内核日志(相当于增强版dmesg),还能查看服务日志、用户日志。
查看内核日志,等价于dmesg的journalctl写法:
bash复制journalctl -k
查看本次启动以来的日志:
bash复制journalctl -b
查看某个服务(比如Nginx)的日志:
bash复制journalctl -u nginx
实时跟踪日志:
bash复制journalctl -f
journalctl和dmesg的本质区别在于:journalctl是把日志结构化管理并落盘(默认存于/var/log/journal/),即使环形缓冲区被新日志覆盖后也能回溯历史;dmesg读的是内存里的环形缓冲区,重启后缓冲区清空,只保留当前开机以来的记录。
如果系统没有安装systemd-journald或者journal文件被清理,journalctl回退到/var/log/messages(CentOS/RHEL系)或/var/log/syslog(Ubuntu/Debian系)。查看内核历史日志的兼容做法是:
bash复制# CentOS/RHEL
grep -i "error" /var/log/messages
# Ubuntu/Debian
grep -i "error" /var/log/syslog
5.3 非systemd环境下的日志查看
CentOS 6、Alpine(OpenRC)等非systemd环境没有journalctl,系统日志由syslog族服务(rsyslog/syslog-ng)管理。传统查看方式:
bash复制tail -f /var/log/messages
tail -f /var/log/secure
/var/log/secure记录登录认证相关的安全日志,排查SSH爆破时比看messages更直观。Ubuntu/Debian对应路径是/var/log/auth.log。
判断当前init系统的兼容命令:
bash复制ps -p 1 -o comm=
输出systemd表示使用systemd,输出init或sysvinit则是SysV init环境。在脚本里可以根据这个返回值决定用journalctl还是直接读日志文件。
综合来说,日志查看的跨发行版适配策略可以这样定:
| 场景 | systemd环境 | 非systemd环境 |
|---|---|---|
| 查看当前启动内核日志 | journalctl -k -b |
dmesg |
| 查看本次启动系统日志 | journalctl -b |
tail -f /var/log/messages |
| 查看登录失败记录 | journalctl -u ssh 或 /var/log/auth.log |
/var/log/secure |
| 实时追踪服务日志 | journalctl -u 服务名 -f |
tail -f /var/log/messages |
| 排查硬件错误 | `journalctl -k | grep -i error` |
6. 实战:编写一个跨发行版的系统信息采集脚本
原理讲清楚了,命令差异也梳理完了,最后落到实战。这里我写一个最小可用的系统信息采集脚本,展示如何通过“命令存在性检测+底层虚拟文件兜底”来保证兼容性。
6.1 发行版识别与命令存在性检测
脚本第一步是识别发行版。由于/etc/os-release在主流发行版上几乎都存在,直接source它是最省事的方式:
bash复制#!/bin/bash
if [ -f /etc/os-release ]; then
. /etc/os-release
OS_ID="$ID"
OS_VERSION="$VERSION_ID"
else
OS_ID=$(uname -s)
OS_VERSION=$(uname -r)
fi
echo "发行版: $OS_ID $OS_VERSION"
第二步是判断命令是否存在。这里用command -v,它在bash和POSIX shell下都可用:
bash复制if command -v lscpu >/dev/null 2>&1; then
CPU_MODEL=$(lscpu | grep "Model name" | cut -d: -f2 | xargs)
else
CPU_MODEL=$(grep "model name" /proc/cpuinfo | head -1 | cut -d: -f2 | xargs)
fi
echo "CPU型号: $CPU_MODEL"
cut -d: -f2提取冒号后面的字段,再用xargs去掉首尾空格。这个写法在lscpu和/proc/cpuinfo两种输出格式下都能正确取到CPU型号,因为两边的字段名都有“model name”或“Model name”这样的关键字。
6.2 内存、磁盘、内核信息的兼容写法
内存信息优先从/proc/meminfo读,避免free输出格式差异:
bash复制MEM_TOTAL=$(awk '/MemTotal/ {printf "%.1f GB", $2/1024/1024}' /proc/meminfo)
if grep -q MemAvailable /proc/meminfo; then
MEM_AVAIL=$(awk '/MemAvailable/ {printf "%.1f GB", $2/1024/1024}' /proc/meminfo)
else
# 老内核没有MemAvailable字段时,用 free+cached 近似估算
MEM_AVAIL=$(awk '/MemFree/ {free=$2} /^Cached/ {cached=$2} END {printf "%.1f GB", (free+cached)/1024/1024}' /proc/meminfo)
fi
echo "内存总量/可用: $MEM_TOTAL / $MEM_AVAIL"
磁盘信息用df -hP /,-P参数强制POSIX格式输出,避免跨系统时行尾自动换行导致解析错乱:
bash复制ROOT_USAGE=$(df -hP / | awk 'NR==2 {print $5}')
echo "根分区使用率: $ROOT_USAGE"
内核信息直接用uname:
bash复制KERNEL=$(uname -r)
ARCH=$(uname -m)
echo "内核/架构: $KERNEL / $ARCH"
6.3 完整示例:只需bash无需额外安装
把以上片段组装成一条完整的采集脚本:
bash复制#!/bin/bash
# 系统信息采集脚本,兼容主流Linux发行版
echo "========== 系统基本信息 =========="
# 发行版识别
if [ -f /etc/os-release ]; then
. /etc/os-release
echo "发行版: $PRETTY_NAME"
else
echo "发行版: $(uname -s) $(uname -r)"
fi
echo "主机名: $(uname -n)"
echo "内核版本: $(uname -r)"
echo "操作系统架构: $(uname -m)"
# CPU信息
echo ""
echo "========== CPU信息 =========="
if command -v lscpu >/dev/null 2>&1; then
echo "逻辑CPU数: $(lscpu | awk '/^CPU\(s\):/ {print $2}')"
echo "物理CPU数: $(lscpu | awk '/^Socket\(s\):/ {print $2}')"
echo "每颗核心数: $(lscpu | awk '/^Core\(s\) per socket:/ {print $4}')"
echo "每核心线程数: $(lscpu | awk '/^Thread\(s\) per core:/ {print $4}')"
else
echo "逻辑CPU数: $(grep -c processor /proc/cpuinfo)"
echo "CPU型号: $(grep "model name" /proc/cpuinfo | head -1 | cut -d: -f2 | xargs)"
fi
# 内存信息
echo ""
echo "========== 内存信息 =========="
awk '/MemTotal/ {printf "内存总量: %.1f GB\n", $2/1024/1024}' /proc/meminfo
if grep -q MemAvailable /proc/meminfo; then
awk '/MemAvailable/ {printf "可用内存: %.1f GB\n", $2/1024/1024}' /proc/meminfo
else
awk '/MemFree/ {free=$2} /^Cached/ {cached=$2} END {printf "可用内存(估算): %.1f GB\n", (free+cached)/1024/1024}' /proc/meminfo
fi
# 磁盘信息
echo ""
echo "========== 磁盘信息 =========="
df -hP | awk 'NR==1 || /^\/dev\// {print}'
echo "根分区使用率: $(df -hP / | awk 'NR==2 {print $5}')"
# 如有lsblk则同时输出块设备拓扑
if command -v lsblk >/dev/null 2>&1; then
echo ""
echo "========== 块设备拓扑 =========="
lsblk
fi
这个脚本不依赖任何第三方软件包,只在lscpu、lsblk存在时可选的输出增强信息。直接复制到机器上就能运行,不管是CentOS、Ubuntu还是Alpine的BusyBox环境,只要有bash就能跑。
6.4 脚本编写时的几个真实体会
写这种采集脚本,我吃过几次亏,总结成几条经验:
第一,不要迷信命令输出格式的稳定性。 不同版本的lscpu字段名大小写有差异:老版本是CPU(s):,某些新版本用CPU(s):保持不变,但个别语言环境(比如设置了LANG=zh_CN.UTF-8)下字段名可能变为中文。为了稳妥,脚本里最好固定LC_ALL=C再用命令,或者在解析前先export LC_ALL=C。这个坑很隐蔽,我曾经在一台配置了中文locale的服务器上跑采集脚本,所有的awk解析全部失效,排查了半天才发现是locale导致的。
第二,root权限不是默认有的。 有些命令(如dmidecode、dmesg的部分功能)需要root权限,如果脚本以普通用户运行时希望能自动降级跳过,别让脚本直接报错退出:
bash复制if [ "$(id -u)" -eq 0 ] && command -v dmidecode >/dev/null 2>&1; then
dmidecode -t system | grep -E "Manufacturer|Product Name"
else
echo "非root用户或dmidecode未安装,跳过硬件信息采集"
fi
第三,输出时间戳时注意不同发行版的date语法差异。 date +%Y-%m-%d在所有主流发行版都支持,是跨平台最稳的格式。避免使用GNU date特有的date -d、date -I等参数,在BusyBox环境可能不支持。如果脚本需要做日期运算,优先用date -u +%s获取Unix时间戳来算,这个参数在所有环境下都可用。
最后再分享一个实用小技巧
日常排查时不需要总是敲完整命令。在.bashrc或.zshrc里加上这几个别名,可以大幅提升系统信息查看的效率:
bash复制alias cpu='lscpu | grep -E "Model name|^CPU\(s\)|Socket|Core|Thread"'
alias mem='free -h'
alias disk='df -hT'
alias block='lsblk -f'
alias hw='sudo dmidecode -t system | grep -E "Manufacturer|Product Name|Serial"'
alias kern='uname -a'
配置好之后,每次登录服务器只需要敲cpu、mem、disk就能快速看到关键信息。跨发行版使用时这套别名完全通用,因为底层依赖的命令在各发行版上的核心行为是一致的。
系统信息查看看着基础,但正是这些细节决定了排查故障时的效率。下次再遇到一台新发行版的服务器,先按本文的思路跑一遍:确认发行版、查内核、看CPU内存磁盘、检查外设驱动、翻日志,这套流程走完基本就对这台机器的健康状况心里有数了。
