如何防止我的 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)
我正在编写一个脚本,该脚本会持续监控通过 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)