uname(Unix Name)用于输出当前系统的内核和硬件架构信息。它是一个 POSIX 标准命令,在 Linux、macOS、BSD 等系统上均可使用,是运维脚本中获取系统环境信息的首选工具。

在跨平台部署脚本中,uname -s 是判断操作系统的第一行代码;在编译内核模块时,uname -r 决定了模块文件的存放路径。

语法

uname [选项]

选项

选项 含义 示例输出
-a 全部信息 Linux hostname 5.15.0-91-generic #101-Ubuntu SMP ... x86_64 GNU/Linux
-s 内核名称 Linux
-n 网络主机名 webserver01
-r 内核版本号 5.15.0-91-generic
-v 内核版本编译时间 #101-Ubuntu SMP Tue Nov 14 10:30:00 UTC 2025
-m 硬件架构 x86_64
-p 处理器类型 x86_64(通常与 -m 相同)
-i 硬件平台 x86_64(已过时,常返回 unknown)
-o 操作系统名称 GNU/Linux

基础用法

1. 最常用:uname -a

# 一次性获取所有系统信息
uname -a
# Linux webserver01 5.15.0-91-generic #101-Ubuntu SMP Tue Nov 14 10:30:00 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux

# 分解解读:
# Linux          内核名称
# webserver01    主机名
# 5.15.0-91      内核版本
# generic        内核类型
# #101-Ubuntu... 编译信息
# x86_64         硬件架构
# GNU/Linux      操作系统类型

2. 脚本中判断操作系统类型

#!/bin/bash
# 根据 uname -s 判断操作系统并执行相应操作
detect_os() {
    case "$(uname -s)" in
        Linux)
            echo "==检测到 Linux 系统=="
            # Linux 特定操作
            if [ -f /etc/os-release ]; then
                . /etc/os-release
                echo "发行版: $NAME $VERSION"
            fi
            ;;
        Darwin)
            echo "==检测到 macOS 系统=="
            # macOS 特定操作
            sw_vers
            ;;
        CYGWIN*|MINGW*|MSYS*)
            echo "==检测到 Windows (Cygwin/MSYS2/Git Bash)=="
            ;;
        FreeBSD)
            echo "==检测到 FreeBSD 系统=="
            freebsd-version
            ;;
        *)
            echo "==未知系统: $(uname -s)=="
            ;;
    esac

    echo "架构: $(uname -m)"
    echo "内核: $(uname -r)"
}

detect_os

3. 内核模块编译中 uname -r 的用法

# 内核模块必须与当前运行的内核版本匹配
KERNEL_VERSION=$(uname -r)
echo "当前内核版本: $KERNEL_VERSION"

# 内核模块默认安装路径
MODULE_DIR="/lib/modules/$KERNEL_VERSION"
echo "模块目录: $MODULE_DIR"
ls -la "$MODULE_DIR/"

# 编译内核模块时的 Makefile
cat << 'EOF'
# Makefile 示例
obj-m += mydriver.o

# 自动使用当前内核的构建目录
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

all:
    $(MAKE) -C $(KDIR) M=$(PWD) modules

clean:
    $(MAKE) -C $(KDIR) M=$(PWD) clean
EOF

# 安装模块
sudo make -C "/lib/modules/$(uname -r)/build" M="$(pwd)" modules_install
sudo depmod -a

4. 收集完整的系统信息报告

#!/bin/bash
# 生成系统信息报告
report_file="system_report_$(date +%Y%m%d_%H%M%S).txt"

{
    echo "=========================================="
    echo "  系统信息报告"
    echo "  生成时间: $(date)"
    echo "=========================================="
    echo ""

    echo "== uname 信息 =="
    echo "全部信息  : $(uname -a)"
    echo "内核名称  : $(uname -s)"
    echo "主机名    : $(uname -n)"
    echo "内核版本  : $(uname -r)"
    echo "硬件架构  : $(uname -m)"
    echo "操作系统  : $(uname -o)"

    echo ""
    echo "== 发行版信息 =="
    if [ -f /etc/os-release ]; then
        cat /etc/os-release
    fi

    echo ""
    echo "== CPU 信息 =="
    grep "model name" /proc/cpuinfo | head -1
    echo "CPU 核心数: $(nproc)"

    echo ""
    echo "== 内存信息 =="
    free -h

    echo ""
    echo "== 磁盘使用 =="
    df -h /

} > "$report_file"

echo "报告已保存至: $report_file"

5. 根据架构下载对应的二进制包

#!/bin/bash
# 根据系统架构下载正确的软件包
ARCH=$(uname -m)

# 架构映射(不同项目命名规则不同)
case "$ARCH" in
    x86_64)
        GO_ARCH="amd64"
        DOCKER_ARCH="amd64"
        ;;
    aarch64|arm64)
        GO_ARCH="arm64"
        DOCKER_ARCH="arm64"
        ;;
    armv7l)
        GO_ARCH="armv7"
        DOCKER_ARCH="armhf"
        ;;
    *)
        echo "不支持的架构: $ARCH"
        exit 1
        ;;
esac

echo "检测到架构: $ARCH → Go: $GO_ARCH, Docker: $DOCKER_ARCH"

# 下载对应架构的 Go 二进制包
GO_VERSION="1.21.0"
GO_URL="https://go.dev/dl/go${GO_VERSION}.linux-${GO_ARCH}.tar.gz"
echo "下载地址: $GO_URL"
# wget "$GO_URL"

# 下载对应架构的 Docker 二进制包
DOCKER_URL="https://download.docker.com/linux/static/stable/${DOCKER_ARCH}/docker-24.0.0.tgz"
echo "Docker 下载地址: $DOCKER_URL"

6. 编写跨平台兼容代码

#!/bin/bash
# 为不同内核版本和架构编写兼容代码
KERNEL_MAJOR=$(uname -r | cut -d. -f1)
KERNEL_MINOR=$(uname -r | cut -d. -f2)

echo "内核主版本: $KERNEL_MAJOR, 次版本: $KERNEL_MINOR"

# 5.x 内核特性判断
if [ "$KERNEL_MAJOR" -ge 5 ]; then
    echo "使用 WireGuard 内核模块(5.x+ 原生支持)"
    MODE="kernel"
elif [ "$KERNEL_MAJOR" -ge 4 ]; then
    echo "内核版本 4.x,需要使用 DKMS 编译 WireGuard"
    MODE="dkms"
else
    echo "内核版本过低 ($KERNEL_MAJOR.$KERNEL_MINOR),WireGuard 不受支持"
    MODE="unsupported"
fi

# 硬件架构判断
ARCH=$(uname -m)
if [ "$ARCH" = "x86_64" ]; then
    echo "64 位 x86 架构,可使用 AVX2 优化"
elif [ "$ARCH" = "aarch64" ]; then
    echo "ARM 64 位架构,注意 Big/Little 核心调度"
fi

7. 主机名获取的多种方式对比

# 方法1: uname -n
echo "uname -n: $(uname -n)"

# 方法2: hostname 命令
echo "hostname: $(hostname)"

# 方法3: hostname -f (FQDN)
echo "FQDN: $(hostname -f 2>/dev/null || echo '未设置')"

# 方法4: /etc/hostname 文件
echo "配置的主机名: $(cat /etc/hostname 2>/dev/null || echo 'N/A')"

# 方法5: hostnamectl (systemd 系统)
echo "hostnamectl: $(hostnamectl --static 2>/dev/null || echo 'N/A')"

# 区别说明:
# uname -n 返回内核记录的主机名
# hostname 可动态修改(hostname newname)
# hostnamectl 是 systemd 的推荐方式,支持静态/瞬态/灵活三种主机名

8. 监控内核版本变更

#!/bin/bash
# 保存内核版本快照,用于检测内核升级
SNAPSHOT_FILE="/var/log/kernel_version_snapshot.txt"

if [ ! -f "$SNAPSHOT_FILE" ]; then
    # 创建初始快照
    uname -r > "$SNAPSHOT_FILE"
    echo "已创建内核版本快照: $(cat $SNAPSHOT_FILE)"
else
    PREVIOUS=$(cat "$SNAPSHOT_FILE")
    CURRENT=$(uname -r)

    if [ "$PREVIOUS" != "$CURRENT" ]; then
        echo "==内核版本已变更!=="
        echo "之前: $PREVIOUS"
        echo "现在: $CURRENT"
        echo "请注意: 可能需要重新编译内核模块、重新配置 DKMS"

        # 更新快照
        uname -r > "$SNAPSHOT_FILE"

        # 列出需要重新编译的模块
        echo ""
        echo "==当前的模块目录: =="
        ls /lib/modules/
        echo ""
        echo "==当前内核正在使用的模块: =="
        lsmod | head -5
    else
        echo "内核版本未变更: $CURRENT"
    fi
fi
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐