[英]BASH : How to make a script that make “tail -f” always logging the last file in a directory, live
I'm basically trying to make debugging easier for other scripts of mine.我基本上是在尝试让我的其他脚本更容易调试。
(Centos 7.6) (Centos 7.6)
What I need is a script doing:我需要的是一个脚本:
This is my non working solution:这是我的非工作解决方案:
CURRENT_FILE=`ls -1t | head -n1`
tail -n 100 -f "$CURRENT_FILE" &
PID=$!
while [ true ];
do
#is there a new file in the directory ?
NEW_FILE=`ls -1t | head -n1`
if [[ "$CURRENT_FILE" != "$NEW_FILE" ]]; then
#yes, so kill last tail
kill -9 $PID
clear
#tail on the new file
CURRENT_FILE=$NEW_FILE
tail -n 100 -f "$CURRENT_FILE"
PID=$!
fi
sleep 1s
done
The problem with this solution is that when I'm sending SIGINT (Ctrl+C), what I normally do when exiting a "tail -f", it leaves an orphan child in the background.这个解决方案的问题是,当我发送 SIGINT (Ctrl+C) 时,我通常在退出“tail -f”时会执行此操作,它会在后台留下一个孤儿。 I've searched solution with "trap" but I don't get it well, and it doesn't seem to work with an eternal process like "tail -f".我已经用“trap”搜索了解决方案,但我没有得到很好的解决方案,而且它似乎不适用于像“tail -f”这样的永恒过程。
I'll be glad to here your thoughts about that and get into advanced bash programming.我很高兴在这里看到您对此的想法并进入高级 bash 编程。
You can trap
whenever the script exits and kill the process then.您可以在脚本退出时trap
并随后终止该进程。 You don't need -9
to kill your tail
though, that's overkill.你不需要-9
来杀死你的tail
,那太矫枉过正了。
You can also use inotify
to tell you when something happens in the directory instead of sleeping and rechecking.您还可以使用inotify
告诉您目录中何时发生某些事情,而不是休眠和重新检查。 Here's a basic building block.这是一个基本的构建块。 inotify
has a lot of events you can wait for. inotify
有很多你可以等待的事件。 You can add detection if the file was moved/renamed so you don't have to restart the tail
in those cases etc.如果文件被移动/重命名,您可以添加检测,这样您就不必在这些情况下重新启动tail
等。
#!/bin/bash
killpid() {
if [[ -n $PID ]]; then
kill $PID
PID=""
fi
}
trap killpid EXIT
DIR="."
CURRENT_FILE="$(ls -1t "$DIR" | head -n1)"
tailit() {
echo "::: $CURRENT_FILE :::"
tail -n 100 -f "$CURRENT_FILE" &
PID=$!
}
tailit
# wait for any file to be created, modified or deleted
while EVENT=$(inotifywait -q -e create,modify,delete "$DIR"); do
# extract event
ev=$(sed -E "s/^${DIR}\/ (\S+) .+$/\1/" <<< "$EVENT")
# extract the affected file
NEW_FILE=${EVENT#${DIR}/ $ev }
case $ev in
MODIFY)
# start tailing the file if we aren't tailing it already
if [[ $NEW_FILE != $CURRENT_FILE ]]; then
killpid
CURRENT_FILE="$NEW_FILE"
tailit
fi
;;
CREATE)
# a new file, tail it
killpid
CURRENT_FILE="$NEW_FILE"
tailit
;;
DELETE)
# stop tailing if the file we are tailing was deleted
if [[ $NEW_FILE == $CURRENT_FILE ]]; then
echo "::: $CURRENT_FILE removed :::"
CURRENT_FILE=""
killpid
fi
;;
esac
done
You can use trap
solution at the beginning of your shell.您可以在 shell 的开头使用trap
解决方案。
#! /bin/bash
trap ctrl_c INT
function ctrl_c() {
if [[ -n "$PID" ]]; then
kill -9 $PID
fi
exit 0
}
CURRENT_FILE=`ls -1t | head -n1`
tail -n 100 -f "$CURRENT_FILE" &
PID=$!
while [ true ];
do
#is there a new file in the directory ?
NEW_FILE=`ls -1t | head -n1`
if [[ "$CURRENT_FILE" != "$NEW_FILE" ]]; then
#yes, so kill last tail
kill -9 $PID
clear
#tail on the new file
CURRENT_FILE=$NEW_FILE
tail -n 100 -f "$CURRENT_FILE" &
PID=$!
fi
sleep 1s
done
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.