You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Shell脚本中转换Linux cpuset格式并实现遍历?

解决Linux sysfs CPU ID格式转Shell可遍历列表的问题

我之前也碰到过这个棘手的问题!sysfs里用0,2,4-6,8这种紧凑格式表示CPU集合,确实没法直接在Shell的for循环里遍历。下面给你分享两种实用的转换方法,能把它变成0 2 4 5 6 8这种空格分隔的常规格式:

方法一:纯Bash实现(无外部依赖)

这种方法不需要额外安装工具,完全用Bash内置命令就能完成,适合最小化系统或者对依赖要求严格的场景:

# 示例输入,也可以替换成$(cat /sys/devices/system/cpu/online)
cpu_input="0,2,4-6,8"

# 按逗号拆分输入为数组
IFS=, read -ra cpu_parts <<< "$cpu_input"

# 初始化结果字符串
cpu_result=""

# 遍历每个拆分后的元素
for part in "${cpu_parts[@]}"; do
    # 判断当前元素是否是范围格式(包含"-")
    if [[ "$part" == *-* ]]; then
        # 拆分范围的起始和结束值
        IFS=- read start_cpu end_cpu <<< "$part"
        # 生成范围内的所有CPU ID
        for ((cpu_id=start_cpu; cpu_id<=end_cpu; cpu_id++)); do
            cpu_result+="$cpu_id "
        done
    else
        # 如果是单个CPU ID,直接添加到结果
        cpu_result+="$part "
    fi
done

# 移除结果末尾多余的空格
clean_cpu_list=$(echo "$cpu_result" | sed 's/ $//')

# 输出转换后的列表
echo "$clean_cpu_list"

执行后会输出:0 2 4 5 6 8,这时你就可以直接用for cpu in $clean_cpu_list; do ...; done来遍历了。

方法二:用Awk快速实现(简洁高效)

如果你系统里有Awk工具,一行命令就能搞定转换,代码更简洁:

# 直接转换输入字符串
echo "0,2,4-6,8" | awk -F, '{
    for(i=1; i<=NF; i++) {
        split($i, range, "-")
        if (range[2]) {
            for(j=range[1]; j<=range[2]; j++) {
                printf "%d ", j
            }
        } else {
            printf "%d ", range[1]
        }
    }
}' | sed 's/ $//'

如果要直接读取sysfs的CPU在线状态,把echo换成cat即可:

cat /sys/devices/system/cpu/online | awk -F, '{
    for(i=1; i<=NF; i++) {
        split($i, range, "-")
        if (range[2]) {
            for(j=range[1]; j<=range[2]; j++) {
                printf "%d ", j
            }
        } else {
            printf "%d ", range[1]
        }
    }
}' | sed 's/ $//'

两种方法都能完美解决问题,你可以根据自己的场景选择合适的方式~

内容的提问来源于stack exchange,提问作者Ryan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:07:06