[other] 国产系统信息导出脚本
Tofloor
poster avatar
deepin
2025-12-02 09:11
Author

支持从当前系统或PE系统下导出系统信息。

请大佬们帮忙完善系统激活信息的获取和导出,我没有已激活的uos系统。

#!/bin/bash

功能:获取当前系统或LiveCD系统下获取原系统信息。计算机名,IP,系统版本,用户账户,免密权限,共享文件夹,已安装打印机。当前电脑硬件信息。 By Wqlsoft

20251127 测试uos,银河麒麟v10 sp1 2403 , 方德系统当前系统下正常。

20251127 测试uos,银河麒麟v10 sp1 2403 , 方德系统在LiveCD系统下获取原系统信息正常。

20251201 增加uos,银河麒麟v10 sp1 2403 , 方德系统的激活信息备份,目前只测试银河麒麟v10 sp1激活信息备份有效。手里无其它激活的系统。

20251202 修改SUDO 密码输入提示。

==================== 全局变量声明 ====================

CURRENT_ROOT="/" # 当前操作的系统根路径
MOUNTED_SYSTEM_ROOT="" # LiveCD 中挂载的原系统路径
DESKTOP_DIR="" # 桌面目录(真实用户)
OUTPUT_FILE="" # 输出文件路径

NM_CONNECTIONS_DIR=""
SAMBA_USERSHARES_DIR=""
SAMBA_CONF_FILE=""

IS_LIVECD=false
IS_CHROOTED=false

==================== 获取原始用户信息(关键修复)====================

REAL_USER="​{SUDO_USER:-USER}"
if [ "​REAL_USER" = "root" ] || [ -z "REAL_USER" ]; then
REAL_HOME="/root"
else
REAL_HOME=​(getent passwd "REAL_USER" 2>/dev/null | cut -d: -f6)
if [ -z "​REAL_HOME" ] || [ ! -d "REAL_HOME" ]; then
REAL_HOME="/home/$REAL_USER"
fi
fi

==================== 工具函数 ====================

check_root() {
if [ "$EUID" -ne 0 ]; then
echo "❌ 需要 root 权限来执行 chroot 或读取系统文件"
echo "正在尝试通过 sudo 重新运行..."

使用 exec 替换当前进程,避免双重退出

exec sudo -- "$0" "$@"

如果上面失败(比如用户取消密码输入),脚本会在此处终止

echo "sudo 执行失败,退出。"
exit 1
fi
}

detect_environment() {
if grep -q -E "live|casper|boot=casper" /proc/cmdline 2>/dev/null; then
IS_LIVECD=true
echo "✅ 检测到正在 Live CD 环境中运行"
else
IS_LIVECD=false
echo "✅ 正在原系统中运行"
fi
}

自动探测桌面目录(基于真实用户)

detect_desktop_dir() {
if [ -d "$REAL_HOME/Desktop" ]; then
DESKTOP_DIR="$REAL_HOME/Desktop"
elif [ -d "$REAL_HOME/桌面" ]; then
DESKTOP_DIR="$REAL_HOME/桌面"
else
DESKTOP_DIR="$REAL_HOME"
echo "⚠️ 未找到 Desktop 或 桌面 目录,输出将保存到 $DESKTOP_DIR"
fi
}

setup_paths() {
if [ "$IS_LIVECD" = true ]; then
MOUNTED_SYSTEM_ROOT=""
echo "🔍 正在自动探测原系统根目录..."

    # 候选路径:覆盖常见国产系统挂载风格
    for candidate in /media/*/* /media/uos/* /mnt; do
        # 跳过无效或非目录项
        [ -d "$candidate" ] || continue
        # 排除 Live 系统自身 overlay(防止误判)
        case "$candidate" in
            */run/live/overlay|*/usr/lib/live/mount/*|*/tmp/*|*/dev/*|*/proc/*|*/sys/*)
                continue
                ;;
        esac
        # 检查是否包含典型 Linux 根目录特征文件
        if [ -f "$candidate/etc/passwd" ] && [ -f "$candidate/etc/os-release" ]; then
            MOUNTED_SYSTEM_ROOT="$candidate"
            echo "✅ 自动检测到原系统根目录: $MOUNTED_SYSTEM_ROOT"
            break
        fi
    done

    if [ -z "$MOUNTED_SYSTEM_ROOT" ] || [ ! -d "$MOUNTED_SYSTEM_ROOT/etc" ]; then
        echo "❌ 未找到有效的原系统根目录(请确认硬盘已挂载且包含 Linux 系统)"
        echo "   尝试检查:ls /media/"
        exit 1
    fi

    CURRENT_ROOT="$MOUNTED_SYSTEM_ROOT"
    echo "📁 原系统挂载路径: $CURRENT_ROOT"
else
    CURRENT_ROOT="/"
fi

NM_CONNECTIONS_DIR="$CURRENT_ROOT/etc/NetworkManager/system-connections"
SAMBA_USERSHARES_DIR="$CURRENT_ROOT/var/lib/samba/usershares"
SAMBA_CONF_FILE="$CURRENT_ROOT/etc/samba/smb.conf"
detect_desktop_dir
OUTPUT_FILE="$DESKTOP_DIR/本机信息.txt"
echo "📄 输出文件: $OUTPUT_FILE"

}

确保 OUTPUT_FILE 路径有效且可写

ensure_output_file_ready() {
if [ -z "$OUTPUT_FILE" ]; then
echo "❌ 错误:OUTPUT_FILE 未设置!"
exit 1
fi

local output_dir
output_dir="$(dirname "$OUTPUT_FILE")"

if ! mkdir -p "$output_dir" 2>/dev/null; then
    echo "❌ 无法创建输出目录: $output_dir"
    exit 1
fi

if ! touch "$OUTPUT_FILE" 2>/dev/null || ! [ -w "$OUTPUT_FILE" ]; then
    echo "❌ 无法写入输出文件: $OUTPUT_FILE(请检查权限或磁盘空间)"
    exit 1
else
    # 清空文件内容
    > "$OUTPUT_FILE"
fi

}

log() {
if [ "$IS_CHROOTED" = "true" ]; then
cat
else
tee -a "$OUTPUT_FILE"
fi
}

separator() {
echo "================================================================" | log
}

==================== 信息采集函数 ====================

获取指定网络接口的实际 MAC 地址(安全版,永不失败)

get_actual_mac_by_interface() {
local iface="$1"
if [ -z "$iface" ]; then
echo "N/A"
return 0
fi
local addr_file="/sys/class/net/$iface/address"
if [ ! -f "$addr_file" ]; then
echo "接口不存在"
return 0
fi

安全读取 MAC,转小写,清理空白字符

local mac
mac=​(cat "addr_file" 2>/dev/null) || mac=""
if [ -n "$mac" ]; then
echo "$mac" | tr '[:upper:]' '[:lower:]' | tr -d '\r\n\t '
else
echo "无法读取"
fi
}

parse_nm_connection() {
local file="$1"
[ ! -f "$file" ] && return

local name="$(basename "$file")"
name="${name%.nmconnection}"
echo " 连接名称: $name" | log

local content
if ! content=$(cat "$file" 2>/dev/null); then
    echo " ⚠️ 权限不足,无法读取详细配置" | log
    return
fi

# 提取 interface-name(绑定接口)
local iface_name=""
iface_line=$(echo "$content" | grep -i '^[[:space:]]*interface-name[[:space:]]*=' | head -n1)
if [ -n "$iface_line" ]; then
    iface_name=$(echo "$iface_line" | cut -d'=' -f2 | xargs)
fi

if [ -n "$iface_name" ]; then
    echo " 绑定接口: $iface_name" | log
    local actual_mac
    actual_mac=$(get_actual_mac_by_interface "$iface_name")
    echo " 实际 MAC: $actual_mac" | log
else
    echo " 绑定接口: 未指定(自动匹配)" | log
fi

# 提取配置的 MAC 地址
local mac_config=""
mac_line=$(echo "$content" | grep -i '^[[:space:]]*mac-address[[:space:]]*=' | head -n1)
if [ -n "$mac_line" ]; then
    mac_config=$(echo "$mac_line" | cut -d'=' -f2 | xargs)
    if [ -n "$mac_config" ]; then
        mac_config=$(echo "$mac_config" | tr '[:upper:]' '[:lower:]')
        echo " 配置 MAC: $mac_config" | log
    else
        echo " 配置 MAC: 使用硬件默认值" | log
    fi
else
    echo " 配置 MAC: 使用硬件默认值" | log
fi

# 类型判断
if echo "$content" | grep -q '^\[802-11-wireless\]'; then
    echo " 类型: 无线 (Wi-Fi)" | log
elif echo "$content" | grep -q '^\[ethernet\]'; then
    echo " 类型: 以太网" | log
else
    echo " 类型: 未知" | log
fi

# IPv4 方法
local ipv4_method=""
method_line=$(echo "$content" | grep -i '^[[:space:]]*method[[:space:]]*=' | head -n1)
if [ -n "$method_line" ]; then
    ipv4_method=$(echo "$method_line" | cut -d'=' -f2 | xargs)
fi

case "${ipv4_method,,}" in
    manual)
        echo " IPv4方法: 手动(静态IP)" | log
        local addr_line=$(echo "$content" | grep -oP '^address1=\K.*' | head -n1 | tr -d '\r\n')
        if [[ -n "$addr_line" ]]; then
            local ip=$(echo "$addr_line" | cut -d',' -f1 | xargs)
            local gw=$(echo "$addr_line" | cut -d',' -f2 | xargs)
            [ -n "$ip" ] && echo " IP地址: $ip" | log
            [ -n "$gw" ] && echo " 网关: $gw" | log
        fi
        ;;
    auto)
        echo " IPv4方法: 自动(DHCP)" | log
        ;;
    "")
        echo " IPv4方法: 未配置" | log
        ;;
    *)
        echo " IPv4方法: $ipv4_method" | log
        ;;
esac

# DNS
local dns_line=$(echo "$content" | grep -oP '^dns=\K.*' | head -n1 | tr -d '\r\n')
if [[ -n "$dns_line" ]]; then
    IFS=';' read -ra dns_arr <<< "$dns_line"
    local dns_clean=()
    for d in "${dns_arr[@]}"; do
        d_trimmed=$(echo "$d" | xargs)
        if [[ -n "$d_trimmed" ]]; then
            dns_clean+=("$d_trimmed")
        fi
    done
    if [ ${#dns_clean[@]} -gt 0 ]; then
        for dns in "${dns_clean[@]}"; do
            echo " DNS: $dns" | log
        done
    fi
fi

echo "" | log

}

收集 NetworkManager 网络连接信息

collect_network_info() {
separator
echo "网络连接配置:" | log

if [ ! -d "$NM_CONNECTIONS_DIR" ]; then
    echo "未找到 NetworkManager 连接配置目录: $NM_CONNECTIONS_DIR" | log
    return
fi

# 启用 nullglob 避免空匹配问题
local old_nullglob=$(shopt -p nullglob)
shopt -s nullglob

local connections=("$NM_CONNECTIONS_DIR"/*.nmconnection)

if [ ${#connections[@]} -eq 0 ] || [ ! -e "${connections[0]}" ]; then
    echo "未找到任何 NetworkManager 连接配置文件" | log
else
    for conn in "${connections[@]}"; do
        parse_nm_connection "$conn"
    done
fi

# 恢复 nullglob 原始状态
eval "$old_nullglob" 2>/dev/null || shopt -u nullglob

}

get_share_info() {
echo "=== 当前系统所有共享文件夹 ===" | log
local shares_found=0

if [ -d "$SAMBA_USERSHARES_DIR" ]; then
    for share_file in "$SAMBA_USERSHARES_DIR"/*; do
        if [ -f "$share_file" ]; then
            local sharename=""
            local path=""
            while IFS='=' read -r key value; do
                case "$key" in
                    sharename) sharename="$value" ;;
                    path)      path="$value" ;;
                esac
            done < "$share_file"
            if [ -n "$sharename" ] && [ -n "$path" ]; then
                echo "【手动临时共享】$sharename -> $path" | log
                shares_found=1
            fi
        fi
    done
fi

if [ -f "$SAMBA_CONF_FILE" ]; then
    local section=""
    local in_global=0
    while IFS= read -r line || [ -n "$line" ]; do
        line=$(echo "$line" | sed 's/[[:space:]]*;.*$//' | sed 's/[[:space:]]*#.*$//')
        line=$(echo "$line" | xargs)
        [ -z "$line" ] && continue

        if [[ "$line" == \[*\] ]]; then
            section="${line#[}"
            section="${section%]}"
            section=$(echo "$section" | xargs)
            case "$section" in
                global|printers|'print$') in_global=1 ;;
                *) in_global=0 ;;
            esac
            continue
        fi

        if [ "$in_global" -eq 0 ] && [ -n "$section" ]; then
            if [[ "$line" == path[[:space:]]*=* ]]; then
                local p=$(echo "$line" | cut -d'=' -f2- | xargs)
                if [ -n "$p" ]; then
                    echo "【Samba配置共享】$section -> $p" | log
                    shares_found=1
                fi
            fi
        fi
    done < "$SAMBA_CONF_FILE"
fi

if [ "$shares_found" -eq 0 ]; then
    echo "未找到任何共享文件夹" | log
fi

}

get_printer_info() {
echo "已安装打印机:" | log
local printers_conf="$CURRENT_ROOT/etc/cups/printers.conf"
if [ -f "$printers_conf" ]; then
echo "解析CUPS打印机配置:" | log
awk '
/^<[Pp]rinter|^<[Dd]efaultPrinter/ {
line = $0 gsub(/^[<[:space:]]/, "", line)
gsub(/>.
$/, "", line)
n = split(line, a, /[[:space:]]+/)
name = (n >= 2) ? a[2] : "unknown"
is_def = (/^<[Dd]efaultPrinter/)
next
}
/^[[:space:]]*DeviceURI[[:space:]]+/ {
sub(/^[[:space:]]*DeviceURI[[:space:]]+/, "")
if (is_def) {
def_name = name; def_uri = $0 } else {
names[++cnt] = name; uris[cnt] = $0 }
}
/^[[:space:]]*Info[[:space:]]+/ {
sub(/^[[:space:]]*Info[[:space:]]+/, "")
if (is_def) {
def_info = $0 } else {
infos[name] = $0 }
}
/^[[:space:]]*State[[:space:]]+/ {
sub(/^[[:space:]]*State[[:space:]]+/, "")
if (is_def) {
def_state = $0 } else {
states[name] = $0 }
}
END {
if (def_name) {
print "默认打印机:"
print " 名称:" def_name
print " 驱动地址:" def_uri
if (def_info) print " 描述:" def_info
if (def_state) print " 状态:" def_state
print ""
}
for (i = 1; i <= cnt; i++) {
print "打印机" i ":"
print " 名称:" names[i]
print " 驱动地址:" uris[i]
if (infos[names[i]]) print " 描述:" infos[names[i]]
if (states[names[i]]) print " 状态:" states[names[i]]
print ""
}
if (!def_name && cnt == 0) {
print "未配置打印机"
}
}' "$printers_conf" | log
else
echo "CUPS打印机配置文件不存在: $printers_conf" | log
fi
}

==================== 收集用户信息 ====================

=====================================================

收集用户信息(基于 /etc/passwd)

collect_user_info() {
separator
echo "用户信息:" | log

local passwd_file="$CURRENT_ROOT/etc/passwd"
if [ ! -f "$passwd_file" ]; then
    echo "❌ 无法找到 passwd 文件: $passwd_file" | log
    return
fi

# 提取 UID >= 1000 的普通用户(排除 nobody、systemd-* 等)
echo "自建用户:" | log
awk -F: -v root="$CURRENT_ROOT" '
    $3 >= 1000 && $1 != "nobody" && $1 !~ /^systemd-/ && $1 !~ /^_.*$/ {
        print "  " $1
    }
' "$passwd_file" | log

if [ ${PIPESTATUS[0]} -ne 0 ]; then
    echo "  (读取失败)" | log
fi

}

收集 Home 目录内容和 /usr 权限(支持独立 home 分区)

collect_home_and_usr_info() {
separator
echo "用户数据目录 Home 目录内容:" | log

# 候选 home 路径列表
local home_candidates=(
    "$CURRENT_ROOT/home"
    "/media/uos/DATA/home"
    "/media/uos/data/home"
    "/media/uos/_dde_data/home"
    "/media/*/*/home"
)

local found_home=""
for candidate in "${home_candidates[@]}"; do
    if [[ "$candidate" == */\** ]]; then
        shopt -s nullglob
        for expanded in $candidate; do
            if [ -d "$expanded" ] && [ -n "$(ls -A "$expanded" 2>/dev/null)" ]; then
                found_home="$expanded"
                break 2
            fi
        done
        shopt -u nullglob
    else
        if [ -d "$candidate" ] && [ -n "$(ls -A "$candidate" 2>/dev/null)" ]; then
            found_home="$candidate"
            break
        fi
    fi
done

if [ -n "$found_home" ]; then
    echo "(Home 路径: $found_home)" | log
    (
        cd "$found_home" || exit 1
        for user_dir in *; do
            if [ -d "$user_dir" ]; then
                # 获取权限(stat 或 ls)
                if command -v stat >/dev/null 2>&1; then
                    perms=$(stat -c "%A" "$user_dir" 2>/dev/null)
                else
                    perms=$(ls -ld "$user_dir" 2>/dev/null | awk '{print $1}')
                fi

                # 获取磁盘用量(du -sh)
                if command -v du >/dev/null 2>&1; then
                    size=$(du -sh "$user_dir" 2>/dev/null | cut -f1)
                else
                    size="N/A"
                fi

                printf "  %-12s  %-6s  %s\n" "$perms" "$size" "$user_dir"
            fi
        done
    ) | log
else
    echo "(未找到有效的非空 Home 目录)" | log
    for cand in "$CURRENT_ROOT/home" "/media/uos/DATA/home" "/media/uos/data/home" "/media/uos/_dde_data/home"; do
        if [ -d "$cand" ]; then
            echo "  检查路径: $cand (存在但为空或不可读)" | log
        fi
    done
fi

echo | log
echo "/usr 目录权限:" | log
ls -ld "$CURRENT_ROOT/usr" 2>/dev/null | log

}

静态分析 sudo 免密配置(不运行 sudo 命令)

collect_sudo_nopasswd_info() {
separator
echo "Sudo 免密权限配置(静态分析):" | log

local sudoers_file="$CURRENT_ROOT/etc/sudoers"
local sudoers_d="$CURRENT_ROOT/etc/sudoers.d"

if [ ! -f "$sudoers_file" ]; then
    echo "  ❌ 未找到 sudoers 文件: $sudoers_file" | log
    return
fi

# 合并主配置和片段
{
    cat "$sudoers_file"
    [ -d "$sudoers_d" ] && find "$sudoers_d" -type f -name "*" -exec cat {} + 2>/dev/null
} | grep -v '^\s*#' | grep -v '^\s*$' | while read -r line; do
    # 匹配包含 NOPASSWD 的行(忽略大小写)
    if echo "$line" | grep -qi 'NOPASSWD'; then
        echo "  ⚠️ 发现免密配置: $line" | log
    fi
done

# 如果没有输出,说明没找到
# 注意:由于管道子 shell,无法直接设标志位,改用临时文件或重写

# 更可靠方式:先收集到变量
local nopasswd_lines
nopasswd_lines=$({
    cat "$sudoers_file"
    [ -d "$sudoers_d" ] && find "$sudoers_d" -type f -exec cat {} + 2>/dev/null
} | grep -v '^\s*#' | grep -vi '^default' | grep -i 'NOPASSWD' || true)

if [ -n "$nopasswd_lines" ]; then
    echo "$nopasswd_lines" | sed 's/^/  /' | log
else
    echo "  未发现 NOPASSWD 免密配置" | log
fi

}

================= 当前机器的硬件信息 =================

=====================================================

收集当前机器的硬件信息(适用于 LiveCD 或原系统)

collect_hardware_info() {
separator
echo "硬件信息:" | log

# CPU
echo "CPU:" | log
if [ -f /proc/cpuinfo ]; then
    grep "model name" /proc/cpuinfo | uniq | sed 's/^/ /' | log
else
    echo " 无法读取 CPU 信息" | log
fi
echo | log

# 内存
echo "内存:" | log
if command -v free >/dev/null 2>&1; then
    free -h | sed 's/^/ /' | log
else
    echo " free 命令不可用" | log
fi
echo | log

# 显卡
echo "显卡:" | log
if command -v lspci >/dev/null 2>&1; then
    vga_output=$(lspci 2>/dev/null | grep -i vga)
    if [ -n "$vga_output" ]; then
        echo "$vga_output" | sed 's/^/ /' | log
    else
        echo " 未检测到 VGA 设备" | log
    fi
else
    echo " lspci 命令不可用(请安装 pciutils)" | log
fi
echo | log

# 网卡
echo "网卡:" | log
if command -v lspci >/dev/null 2>&1; then
    eth_output=$(lspci 2>/dev/null | grep -i ethernet)
    if [ -n "$eth_output" ]; then
        echo "$eth_output" | sed 's/^/ /' | log
    else
        echo " 未检测到 Ethernet 设备" | log
    fi
else
    echo " lspci 命令不可用" | log
fi
echo | log

# 磁盘空间(排除虚拟文件系统)
echo "磁盘使用情况:" | log
if command -v df >/dev/null 2>&1; then
    df -h --output=source,fstype,size,used,avail,pcent,target 2>/dev/null | \
    grep -vE '^(tmpfs|udev|devtmpfs|overlay|none|/dev/loop)' | \
    sed 's/^/ /' | log
else
    echo " df 命令不可用" | log
fi

}

==================== 银河麒麟 V10 激活与硬件信息(仅在 Kylin 系统下执行)====================

collect_kylin_activation_info() {

判断是否为银河麒麟系统:检查 /etc/kylin-release 或 os-release

local kylin_release="$CURRENT_ROOT/etc/kylin-release"
local os_release="$CURRENT_ROOT/etc/os-release"
local is_kylin=false

if [ -f "$kylin_release" ]; then
    is_kylin=true
elif [ -f "$os_release" ]; then
    if grep -qiE 'kylin|kylinos' "$os_release"; then
        is_kylin=true
    fi
fi

# 如果不是银河麒麟系统,直接跳过
if [ "$is_kylin" = false ]; then
    echo "跳过:当前系统(或原系统)不是银河麒麟 V10,不收集激活信息。" | log
    return 0
fi

separator
echo "银河麒麟 V10 激活与硬件信息(静态读取):" | log

# --- 硬件信息(通过当前运行环境的 dmidecode 获取,因需真实硬件)---
if command -v dmidecode >/dev/null 2>&1; then
    local product_name uuid serial_number cpu_version cpu_family

    product_name=$(sudo dmidecode -t 1 2>/dev/null | grep -i 'Product Name' | sed 's/^[^:]*:[[:space:]]*//' | head -n1)
    uuid=$(sudo dmidecode -t 1 2>/dev/null | grep -i 'UUID' | sed 's/^[^:]*:[[:space:]]*//' | head -n1)
    serial_number=$(sudo dmidecode -t 1 2>/dev/null | grep -i 'Serial Number' | awk '{print $NF}' | head -n1)

    cpu_version=$(sudo dmidecode -t 4 2>/dev/null | grep -i 'Version:' | head -n1 | sed 's/^[^:]*:[[:space:]]*//')
    cpu_family=$(sudo dmidecode -t 4 2>/dev/null | grep -i 'Family:' | head -n1 | sed 's/^[^:]*:[[:space:]]*//')

    [ -n "$product_name" ] && echo "电脑品牌型号:$product_name" | log
    [ -n "$uuid" ] && echo "主板 UUID:$uuid" | log
    [ -n "$serial_number" ] && echo "机箱序列号:$serial_number" | log
    [ -n "$cpu_version" ] && echo "CPU 型号:$cpu_version" | log
    [ -n "$cpu_family" ] && echo "CPU 架构:$cpu_family" | log

    # 内存信息
    local mem_output=""
    while IFS= read -r line; do
        if [[ $line == *"Size:"* ]] && [[ $line != *"No Module Installed"* ]]; then
            size=$(echo "$line" | awk '{print $2, $3}')
            # 找下一行 Type
            type_line=""
            while IFS= read -r next; do
                if [[ $next == *"Type:"* ]]; then
                    type_line=$next
                    break
                fi
            done
            mem_type=$(echo "$type_line" | awk '{print $2}')
            mem_output="${mem_output}内存条: ${size}, 类型: ${mem_type:-Unknown}\n"
        fi
    done < <(sudo dmidecode -t 17 2>/dev/null)

    if [ -n "$mem_output" ]; then
        echo -e "$mem_output" | sed 's/^/ /' | log
    fi
else
    echo " ⚠️ dmidecode 未安装,跳过硬件信息采集" | log
fi

# --- 麒麟激活码 ---
local kyactivation_file="$CURRENT_ROOT/etc/.kyactivation"
if [ -s "$kyactivation_file" ]; then
    local raw_code=$(cat "$kyactivation_file" 2>/dev/null)
    if [ -n "$raw_code" ]; then
        local activation_code=$(echo "$raw_code" | tr -d '\n\r' | fold -w4 | paste -sd'-' -)
        echo "麒麟激活码:$activation_code" | log
    fi
else
    echo "麒麟激活码:未找到 /etc/.kyactivation 文件" | log
fi

# --- WPS 序列号 ---
local wps_license="$CURRENT_ROOT/opt/kingsoft/.auth/license2.dat"
if [ -s "$wps_license" ]; then
    local wps_sn=$(tail -c 256 "$wps_license" 2>/dev/null | strings | grep -Eo '[A-Z0-9]{20,}' | head -n1)
    if [ -n "$wps_sn" ]; then
        wps_sn=$(echo "$wps_sn" | fold -w5 | paste -sd'-' -)
        echo "WPS 序列号:$wps_sn" | log
    else
        echo "WPS 序列号:文件存在但未识别出有效序列号" | log
    fi
else
    echo "WPS 序列号:未找到 license2.dat 文件" | log
fi

# --- 客户服务号、注册码等(无文件,无法静态获取)---
echo "客户服务号 / 注册码 / 有效期:需运行 kylin_serial 等命令(未执行)" | log

# --- 备份授权文件 ---
echo "" | log
echo "正在备份麒麟授权文件..." | log

local file1="$CURRENT_ROOT/etc/.kyinfo"
local file2="$CURRENT_ROOT/etc/LICENSE"
local file3="$CURRENT_ROOT/etc/.kyactivation"

local files_to_zip=""
[ -f "$file1" ] && files_to_zip="$files_to_zip $file1"
[ -f "$file2" ] && files_to_zip="$files_to_zip $file2"
[ -f "$file3" ] && files_to_zip="$files_to_zip $file3"

if [ -n "$files_to_zip" ]; then
    local zip_output="$DESKTOP_DIR/麒麟系统授权文件备份.zip"
    if command -v zip >/dev/null 2>&1; then
        if sudo zip -j "$zip_output" $files_to_zip >/dev/null 2>&1; then
            sudo chown "$REAL_USER":"$(id -gn "$REAL_USER")" "$zip_output" 2>/dev/null || true
            echo "✅ 授权文件已备份至:$zip_output" | log
        else
            echo "❌ ZIP 压缩失败(权限或磁盘问题)" | log
        fi
    else
        echo "⚠️ zip 命令未安装,跳过压缩备份" | log
    fi
else
    echo "⚠️ 未找到任何麒麟授权文件(.kyinfo, LICENSE, .kyactivation)" | log
fi

}

==================== 统信 UOS 激活与授权信息(静态读取)====================

collect_uos_activation_info() {

判断是否为统信 UOS 系统

local os_release="$CURRENT_ROOT/etc/os-release"
local is_uos=false

if [ -f "$os_release" ]; then
    if grep -qiE 'UnionTech|uos' "$os_release"; then
        is_uos=true
    fi
fi

# 如果不是 UOS,直接跳过
if [ "$is_uos" = false ]; then
    echo "跳过:当前系统(或原系统)不是统信 UOS,不收集激活信息。" | log
    return 0
fi

separator
echo "统信 UOS 激活与授权信息(静态读取):" | log

local uos_license_dir="$CURRENT_ROOT/etc/uos-license"
local device_id_file="$uos_license_dir/device_id"
local license_file="$uos_license_dir/license.dat"
local serial_files=("$CURRENT_ROOT/etc/.uos_serial" "$CURRENT_ROOT/etc/uos_serial")

# --- 设备 ID ---
if [ -s "$device_id_file" ]; then
    local device_id=$(cat "$device_id_file" 2>/dev/null | tr -d '\n\r')
    echo "UOS 设备ID:$device_id" | log
else
    echo "UOS 设备ID:未找到 $device_id_file" | log
fi

# --- 客户服务号(序列号)---
local found_serial=false
for sf in "${serial_files[@]}"; do
    if [ -s "$sf" ]; then
        local serial=$(cat "$sf" 2>/dev/null | tr -d '\n\r')
        if [ -n "$serial" ]; then
            echo "UOS 客户服务号(序列号):$serial" | log
            found_serial=true
            break
        fi
    fi
done
if [ "$found_serial" = false ]; then
    # 尝试从 license.dat 中提取(部分版本会嵌入)
    if [ -s "$license_file" ]; then
        local extracted_serial=$(sudo strings "$license_file" 2>/dev/null | grep -Eo 'UOS[0-9]{8,}|[0-9]{10,}' | head -n1)
        if [ -n "$extracted_serial" ]; then
            echo "UOS 客户服务号(序列号):$extracted_serial(从 license.dat 提取)" | log
            found_serial=true
        fi
    fi
    if [ "$found_serial" = false ]; then
        echo "UOS 客户服务号(序列号):未找到标准序列号文件" | log
    fi
fi

# --- 授权状态与有效期(尝试解析 license.dat)---
if [ -s "$license_file" ]; then
    # 尝试提取明文字段
    local status_info=$(sudo strings "$license_file" 2>/dev/null | grep -iE 'activated|expired|valid|organization|term' || true)
    if [ -n "$status_info" ]; then
        echo "UOS 授权信息(从 license.dat 提取):" | log
        echo "$status_info" | sed 's/^/  /' | log
    else
        echo "UOS 授权信息:license.dat 存在但无法提取明文信息(可能为加密二进制)" | log
    fi
else
    echo "UOS 授权信息:未找到 /etc/uos-license/license.dat" | log
fi

# --- 备份 uos-license 目录 ---
echo "" | log
echo "正在备份 UOS 授权目录..." | log

if [ -d "$uos_license_dir" ]; then
    local zip_output="$DESKTOP_DIR/UOS系统授权文件备份.zip"
    if command -v zip >/dev/null 2>&1; then
        # 使用 sudo 确保能读取受保护文件
        if sudo zip -r "$zip_output" "$uos_license_dir" >/dev/null 2>&1; then
            sudo chown "$REAL_USER":"$(id -gn "$REAL_USER")" "$zip_output" 2>/dev/null || true
            echo "✅ UOS 授权目录已备份至:$zip_output" | log
        else
            echo "❌ ZIP 压缩失败(权限或磁盘问题)" | log
        fi
    else
        echo "⚠️ zip 命令未安装,跳过压缩备份" | log
    fi
else
    echo "⚠️ 未找到 UOS 授权目录:$uos_license_dir" | log
fi

}

==================== 中科方德(FangDe / NFSChina)系统激活与授权信息(静态读取)====================

collect_fangde_activation_info() {

判断是否为中科方德(FangDe / NFSChina)系统

local os_release="$CURRENT_ROOT/etc/os-release"
local is_fangde=false

if [ -f "$os_release" ]; then
    # 检查 ID 是否为 nfsdesktop(V5.0 典型值)
    if grep -q '^ID=nfsdesktop' "$os_release"; then
        is_fangde=true
    # 或检查 NAME / NAME_EN / HOME_URL 是否包含 FangDe、NFSChina 等关键词
    elif grep -qiE 'FangDe|方德|NFSChina|nfschina\.com' "$os_release"; then
        is_fangde=true
    fi
fi

# 如果不是方德系统,直接跳过
if [ "$is_fangde" = false ]; then
    echo "跳过:当前系统(或原系统)不是中科方德(FangDe/NFSChina),不收集激活信息。" | log
    return 0
fi

separator
echo "中科方德(FangDe / NFSChina)系统激活与授权信息(静态读取):" | log

# 常见授权文件路径(按优先级)
local candidate_files=(
    "$CURRENT_ROOT/etc/.fdinfo"
    "$CURRENT_ROOT/etc/fdinfo"
    "$CURRENT_ROOT/etc/.fdlicense"
    "$CURRENT_ROOT/etc/fdlicense.dat"
    "$CURRENT_ROOT/etc/.nfslicense"
    "$CURRENT_ROOT/etc/nfslicense.dat"
    "$CURRENT_ROOT/var/lib/fd-license/license.dat"
    "$CURRENT_ROOT/etc/nfs-info"
    "$CURRENT_ROOT/etc/.kyinfo"          # 部分早期版本复用 Kylin 文件
    "$CURRENT_ROOT/etc/LICENSE"          # 通用 LICENSE 文件
)

local found_any=false

# 尝试读取每个候选文件
for file in "${candidate_files[@]}"; do
    if [ -s "$file" ]; then
        echo "发现授权文件:$file" | log
        # 提取可读字符串(避免二进制乱码)
        local content
        content=$(sudo strings "$file" 2>/dev/null | head -n 30)
        if [ -n "$content" ]; then
            echo "文件内容(前30行可读字符串):" | log
            echo "$content" | sed 's/^/  /' | log
        else
            echo "  (文件存在但无可读内容)" | log
        fi
        found_any=true
    fi
done

if [ "$found_any" = false ]; then
    echo "⚠️ 未找到任何已知的方德授权文件(.fdinfo, .nfslicense, etc.)" | log
fi

# --- 尝试提取序列号(客户服务号)---
local serial_candidates=()
for file in "${candidate_files[@]}"; do
    if [ -f "$file" ]; then
        # 匹配典型序列号:16~32位字母数字(大写为主)
        local sn=$(sudo strings "$file" 2>/dev/null | grep -Eo '[A-Z0-9]{16,32}' | head -n1)
        if [ -n "$sn" ]; then
            serial_candidates+=("$sn")
        fi
    fi
done

if [ ${#serial_candidates[@]} -gt 0 ]; then
    echo "可能的方德序列号(客户服务号):" | log
    for sn in "${serial_candidates[@]:0:3}"; do
        echo "  $sn" | log
    done
else
    echo "方德序列号:未从授权文件中识别出有效序列号" | log
fi

# --- 备份所有可能的授权文件 ---
echo "" | log
echo "正在备份方德授权相关文件..." | log

local files_to_backup=()
for file in "${candidate_files[@]}"; do
    if [ -f "$file" ]; then
        files_to_backup+=("$file")
    fi
done

if [ ${#files_to_backup[@]} -gt 0 ]; then
    local zip_output="$DESKTOP_DIR/方德系统授权文件备份.zip"
    if command -v zip >/dev/null 2>&1; then
        if sudo zip -j "$zip_output" "${files_to_backup[@]}" >/dev/null 2>&1; then
            sudo chown "$REAL_USER":"$(id -gn "$REAL_USER")" "$zip_output" 2>/dev/null || true
            echo "✅ 方德授权文件已备份至:$zip_output" | log
        else
            echo "❌ ZIP 压缩失败(权限或磁盘问题)" | log
        fi
    else
        echo "⚠️ zip 命令未安装,跳过压缩备份" | log
    fi
else
    echo "⚠️ 无授权文件可备份" | log
fi

}

==================== 主流程 ====================

main() {
check_root
detect_environment
setup_paths # ← 此时 OUTPUT_FILE 已设置

ensure_output_file_ready   # ← 调用新函数

separator
echo "开始收集系统信息... ($(date '+%Y年%m月%d日 %H:%M:%S'))" | log

# ========== 以下为信息采集 ==========

# 0. 计算机名
separator
echo "计算机名:" | log
if [ -f "$CURRENT_ROOT/etc/hostname" ]; then
    cat "$CURRENT_ROOT/etc/hostname" | log
else
    echo "无法找到 /etc/hostname 文件" | log
fi

# 1. 系统版本
separator
echo "系统详细信息:" | log
if [ -f "$CURRENT_ROOT/etc/os-version" ]; then
    cat "$CURRENT_ROOT/etc/os-version" | log
elif [ -f "$CURRENT_ROOT/etc/os-release" ]; then
    echo "=== /etc/os-release ===" | log
    cat "$CURRENT_ROOT/etc/os-release" | log
else
    echo "无法找到系统版本文件" | log
fi

# 2. 用户信息
collect_user_info

# 3. Home 目录与 /usr 权限
collect_home_and_usr_info

# 4. Sudo 免密配置(静态分析)
collect_sudo_nopasswd_info

# 5.硬件信息(总是读当前机器)
collect_hardware_info

# 6. 网络连接
separator
collect_network_info

# 7. 共享文件夹
separator
get_share_info

# 8. 打印机
separator
get_printer_info

separator

# ========== 新增:银河麒麟激活信息 ==========
collect_kylin_activation_info

# ========== 新增:统信 UOS 激活信息 ==========
collect_uos_activation_info

# ========== 新增:中科方德(FangDe)激活信息 ==========
collect_fangde_activation_info

separator

echo "✅ 信息收集完成,结果已保存至:$OUTPUT_FILE"
sleep 30

}

==================== 执行 ====================

main

Reply Favorite View the author
All Replies
deepin
2025-12-02 09:11
#1

UOS1070u4-2025-12-02-08-51-50_看图王.png

Reply View the author
root
deepin
2025-12-02 09:14
#2

首先正常的uos是无发运行sudo的,

安装时选择全盘加密阁下又如何应对

tail

Reply View the author
兆兆嘟嘟嘟
Moderator
2025-12-08 01:00
#3

这些是从哪里收集来的?

Reply View the author
deepin
2025-12-08 16:46
#4
兆兆嘟嘟嘟

这些是从哪里收集来的?

通义ai帮我写的

Reply View the author
晴朗朗朗
deepin
2026-03-12 22:33
#5

楼主能否分享一下这个脚本下载?

谢谢!

Reply View the author