我正在运行一个名为“hd-idle”的应用程序。在特定时间不活动后,它会降低磁盘转速。 输出如下所示:
user@linux:~$ sudo /usr/sbin/hd-idle -i 10800
symlinkPolicy=0, defaultIdle=10800, defaultCommand=scsi, defaultPowerCondition=0, debug=false, logFile=, devices=
sda spindown
sdd spindown
sde spindown
sda spinup
sdd spinup
sdd spindown
[...]
我想将此输出保存到日志文件中(当应用程序运行时),添加时间戳并将 sd[a-z] 更改为硬盘驱动器的相应型号/序列号。
我写了一个小的 bash 脚本来完成我想要的事情:
user@linux:~$ cat hd_idle_logger.sh
#!/bin/bash
DATUM=$(date '+%Y-%m-%d %H:%M:%S')
INPUT=$(cat)
REGEX='(sd[a-z])\s(spin(down|up))'
[[ $INPUT =~ $REGEX ]]
if [ -n ${BASH_REMATCH[1]} ]
then
MODEL=$(lsblk /dev/${BASH_REMATCH[1]} -n -o MODEL)
SERIAL=$(lsblk /dev/${BASH_REMATCH[1]} -n -o SERIAL)
fi
echo -e "$DATUM\t${MODEL}_$SERIAL (${BASH_REMATCH[1]})\t${BASH_REMATCH[2]}" >> /home/linux/hd_idle_logger.log
我可以验证它是否有效:
user@linux:~$ echo "sdd spindown" |& ./hd_idle_logger.sh
user@linux:~$ cat hd_idle_logger.log
2023-02-12 12:14:54 WDC_WD120EMAZ-10BLFA6_1PAEL2ES (sdd) spindown
但是运行应用程序并将输出传递到我的脚本不起作用,日志文件不会生成任何内容,并且我不再在控制台上看到输出:
user@linux:~$ sudo /usr/sbin/hd-idle -i 10800 |& /home/user/hd_idle_logger.sh
只要
hd-idle
正在运行,您的脚本就会卡在 INPUT=$(cat)
。因为 $(cat)
必须捕获所有输出,所以一旦 hd-idle
终止,它就可以在线终止。
您需要一个脚本/程序来动态处理
hd-idle
的输出;例如一行一行地运行,而 hd-idle
仍在运行。您可以使用 while read
循环来完成此操作:
#! /bin/bash
regex='(sd[a-z])\s(spin(down|up))'
while IFS= read -r line; do
[[ $line =~ $regex ]] || continue
model=$(lsblk /dev/"${BASH_REMATCH[1]}" -n -o MODEL)
serial=$(lsblk /dev/"${BASH_REMATCH[1]}" -n -o SERIAL)
printf '%(%Y-%m-%d %H:%M:%S)T\t%s_%s (%s)\t%s\n' \
"$model" "$serial" "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}"
done >> /home/linux/hd_idle_logger.log
但是,切换到
sed
或 awk
等实用程序并预先计算序列号列表或在 /sys/block
文件系统中查找所需信息会更有效,这样您就不需要对每一行执行 lsblk
。