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

如何从hdparm输出的frozen行中提取not关键字?

嘿,我来帮你搞定这个问题!咱们先拆解下你当前脚本的问题,再给你靠谱的解决办法~

问题出在哪?

你的脚本有两个明显的问题:

  1. 语法小bug:echo $is_frozen 前面没加分号或者换行,shell会把它和前面的命令串在一起执行,这会导致异常(不过你说返回frozen,可能是输入时的格式问题,但这个必须先修正)
  2. 逻辑不对:你用awk '/frozen/ { print $1 }',意思是匹配包含frozen的行,然后打印该行的第一个字段,而不是frozen前面紧挨着的那个词,这当然拿不到not啦!

正确的提取方法

要精准拿到frozen前面的not,我们需要让awk找到frozen这个字段,然后输出它的前一个字段。这里有两种稳妥的写法:

写法一:通用遍历匹配(推荐)

这种方法会遍历行内的所有字段,不管frozen在哪个位置,都能找到它并输出前一个词:

for d in $(ls /sys/block); do
  # 屏蔽非SSD设备的hdparm报错,避免干扰输出
  is_frozen=$(hdparm -I /dev/$d 2>/dev/null | awk '{for(i=1;i<=NF;i++){if($i=="frozen") print $(i-1)}}')
  echo "Device /dev/$d - Frozen status prefix: $is_frozen"
done
  • NF是awk的内置变量,表示当前行的总字段数,遍历每个字段找到frozen后,$(i-1)就是它的前一个字段。
  • 加2>/dev/null是为了忽略hdparm对非物理磁盘(比如loop设备、ramdisk)的报错信息,让输出更干净。

写法二:先匹配行再定位

如果你能确定frozen所在行的格式不会变,也可以先匹配包含frozen的行,再在该行内查找:

for d in $(ls /sys/block); do
  is_frozen=$(hdparm -I /dev/$d 2>/dev/null | awk '/frozen/ {for(i=1;i<=NF;i++){if($i=="frozen") print $(i-1)}}')
  echo "Device /dev/$d - Frozen status prefix: $is_frozen"
done

其实和写法一逻辑一致,只是先缩小了处理的行范围,效率差不多,但写法一更通用,适配不同设备的输出差异。

快速测试技巧

你可以先单独针对某个SSD设备测试awk命令,验证是否能拿到not:

hdparm -I /dev/sda | awk '{for(i=1;i<=NF;i++){if($i=="frozen") print $(i-1)}}'

额外优化:只处理SSD设备

用ls /sys/block会拿到所有块设备,包括非SSD的,你可以通过rotational属性过滤出真正的SSD(SSD的rotational值为0,机械盘为1):

for d in $(ls /sys/block); do
  # 判断是否为SSD
  if [ $(cat /sys/block/$d/queue/rotational) -eq 0 ]; then
    is_frozen=$(hdparm -I /dev/$d 2>/dev/null | awk '{for(i=1;i<=NF;i++){if($i=="frozen") print $(i-1)}}')
    echo "SSD /dev/$d - Frozen status prefix: $is_frozen"
  fi
done

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:03:27