Bash 脚本在特定 while/if 循环中挂在 Gotify Push 命令上

Bash 脚本在特定 while/if 循环中挂在 Gotify Push 命令上

我正在构建一个简单的脚本,用于监视正在打开的 su/ssh 会话的 auth.log 。如果它看到使用 su 或 ssh 打开的会话,它会使用 Gotify 发送一条推送消息。我已经测试了 Gotify 命令,将其放入自己的脚本中并运行它,它可以工作,但一旦进入 while 循环,它就会挂起。我从这个问题中找到了解决办法Shell 脚本在邮件命令上挂起通过将输入从 /dev/null 重定向到 gotify 命令,但我不确定为什么我需要在这个特定实例中执行此操作,而不是在其他脚本中使用它时执行此操作(我有一些其他脚本,我在没有重定向)。

脚本是:

#! /bin/bash
pipe=$(mktemp -u)
mkfifo "${pipe}"
log="/var/log/auth.log"

trap "rm -f $pipe" EXIT

tail -f $log >> $pipe &

while read line;
  do
    aryLine=(${line})
    if [[ "${aryLine[@]:5:3}" =~ "pam_unix("(su|sshd)":session): session opened" ]]; then
      echo "session opened for ${aryLine[@]:10:4}"
     /usr/bin/gotify push -p 3 --title "login" "login from ${aryLine[10]}" < /dev/null
    fi
done < $pipe

我不知道为什么在这个特定的 while/if 循环中使用 Gotify 时需要 /dev/null 来停止脚本挂起,任何帮助理解将不胜感激。下面的代码可以正常工作,并且可以很好地向我的gotify发送垃圾邮件:

#! /bin/bash
while true; do
  if true; then
    /usr/bin/gotify push -p 3 --title "login" "login from ${aryLine[10]}"
  fi
done

我正在使用 Debian Bullseye。

答案1

您需要/dev/null重定向,因为整个while .. do .. done < $pipe复合命令设置为从管道读取,包括gotify命令。该gotify命令可能会尝试从其标准输入(现在是管道)读取并阻塞,直到到达文件末尾,这只会在tail终止时发生。重定向允许您在与管道断开连接的情况下</dev/null运行,这样它就不会尝试从中读取数据。gotify

我相信gotify这样做是因为它允许您执行以下操作:

echo "my message" | gotify push

它必须尝试读取其标准输入才能使此功能发挥作用。

相关内容