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

问题描述 投票:0回答:1

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

那么我做错了什么?

bash shell scripting stdout io-redirection
1个回答
0
投票

只要

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

© www.soinside.com 2019 - 2024. All rights reserved.