为什么 bash 脚本停止工作
Why does bash script stop working
该脚本监控传入的 HTTP 消息并将它们转发到名为 zabbix 的监控应用程序,它工作正常,但是大约 1-2 天后它停止工作。这是我目前所知道的:
- 使用
pgrep
我看到脚本仍然是 运行
- 日志文件得到正确更新(脚本的第一个命令)
- FIFO 管道似乎正常工作
问题一定出在 WHILE 循环或 tail 命令中。
我是脚本新手,所以也许有人可以立即发现问题?
#!/bin/bash
tcpflow -p -c -i enp2s0 port 80 | grep --line-buffered -oE 'boo.php.* HTTP/1.[01]' >> /usr/local/bin/logfile &
pipe=/tmp/fifopipe
trap "rm -f $pipe" EXIT
if [[ ! -p $pipe ]]; then
mkfifo $pipe
fi
tail -n0 -F /usr/local/bin/logfile > /tmp/fifopipe &
while true
do
if read line <$pipe; then
unset sn
for ((c=1; c<=3; c++)) # c is no of max parameters x 2 + 1
do
URL="$(echo $line | awk -F'[ =&?]' '{print $'$c'}')"
if [[ "$URL" == 'sn' ]]; then
((c++))
sn="$(echo $line | awk -F'[ =&?]' '{print $'$c'}')"
fi
done
if [[ "$sn" ]]; then
hosttype="US2G_"
host=$hosttype$sn
zabbix_sender -z nuc -s $host -k serial -o $sn -vv
fi
fi
done
您从 fifo 中输入的内容不正确。通过写作:
while true; do read line < $pipe ....; done
您将在循环的每次迭代中关闭并重新打开 fifo。第一次关闭它时,管道的生产者(tail -f)获得 SIGPIPE 并死掉。将结构更改为:
while true; do read line; ...; done < $pipe
请注意,循环内的每个进程现在都有可能无意中从管道读取数据,因此您可能希望为每个进程显式关闭标准输入。
该脚本监控传入的 HTTP 消息并将它们转发到名为 zabbix 的监控应用程序,它工作正常,但是大约 1-2 天后它停止工作。这是我目前所知道的:
- 使用
pgrep
我看到脚本仍然是 运行 - 日志文件得到正确更新(脚本的第一个命令)
- FIFO 管道似乎正常工作
问题一定出在 WHILE 循环或 tail 命令中。 我是脚本新手,所以也许有人可以立即发现问题?
#!/bin/bash
tcpflow -p -c -i enp2s0 port 80 | grep --line-buffered -oE 'boo.php.* HTTP/1.[01]' >> /usr/local/bin/logfile &
pipe=/tmp/fifopipe
trap "rm -f $pipe" EXIT
if [[ ! -p $pipe ]]; then
mkfifo $pipe
fi
tail -n0 -F /usr/local/bin/logfile > /tmp/fifopipe &
while true
do
if read line <$pipe; then
unset sn
for ((c=1; c<=3; c++)) # c is no of max parameters x 2 + 1
do
URL="$(echo $line | awk -F'[ =&?]' '{print $'$c'}')"
if [[ "$URL" == 'sn' ]]; then
((c++))
sn="$(echo $line | awk -F'[ =&?]' '{print $'$c'}')"
fi
done
if [[ "$sn" ]]; then
hosttype="US2G_"
host=$hosttype$sn
zabbix_sender -z nuc -s $host -k serial -o $sn -vv
fi
fi
done
您从 fifo 中输入的内容不正确。通过写作:
while true; do read line < $pipe ....; done
您将在循环的每次迭代中关闭并重新打开 fifo。第一次关闭它时,管道的生产者(tail -f)获得 SIGPIPE 并死掉。将结构更改为:
while true; do read line; ...; done < $pipe
请注意,循环内的每个进程现在都有可能无意中从管道读取数据,因此您可能希望为每个进程显式关闭标准输入。