如何防止我的 bash 脚本(拖尾文件)重复作用于同一行?

How do I prevent my bash script (tailing a file) from repeatedly acting on the same line?

我正在编写一个脚本,该脚本会持续监控通过 ssh 登录到我的服务器或笔记本电脑。

这是我使用的代码。

slackmessenger() {
curl -X POST -H 'Content-type: application/json' --data '{"text":"'""'"}' myapilinkwashere 
## removed it the api link due to slack restriction
}

while true
do
        tail /var/log/auth.log | grep sshd | head -n 1 | while read LREAD
        do
        echo ${LREAD}
        var=$(tail -f /var/log/auth.log | grep sshd | head -n 1)
        slackmessenger "$var"
        done
done

我面临的问题是,由于 while 循环,它一直在发送旧日志。是否存在这样一种情况,即循环只发送新的 entries/updated enter 而不是一遍又一遍地发送旧的。想不出会跳过旧条目而只显示旧条目的条件。

不是使用 head -n 1 一次提取一行,而是迭代 tail -f /var/log/auth.log | grep sshd 的过滤输出并在每行通过时处理一次。

#!/usr/bin/env bash
#              ^^^^- this needs to be a bash script, not a sh script!
case $BASH_VERSION in '') echo "Needs bash, not sh" >&2; exit 1;; esac

while IFS= read -r line; do
  printf '%s\n' "$line"
  slackmessenger "$line"
done < <(tail -f /var/log/auth.log | grep --line-buffered sshd)

参见 BashFAQ #9 描述为什么需要 --line-buffered


你也可以这样写:

#!/usr/bin/env bash
case $BASH_VERSION in '') echo "Needs bash, not sh" >&2; exit 1;; esac

tail -f /var/log/auth.log |
  grep --line-buffered sshd |
  tee >(xargs -d $'\n' -n 1 slackmessenger)