shell 将stderr/-out从正在运行的应用程序重定向到我自己的bash脚本

dgtucam1  于 2023-02-13  发布在  Shell
关注(0)|答案(1)|浏览(141)

我正在运行一个名为“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

所以我做错了什么?

r6l8ljro

r6l8ljro1#

只要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

然而,切换到sedawk这样的实用程序,并预先计算序列号列表或在/sys/block文件系统中查找所需信息,这样效率会更高,这样就不必对每一行都执行lsblk

相关问题