我基本上是想使我的其他脚本的调试更容易。
(Centos 7.6)
我需要做的是一个脚本:
这是我不工作的解决方案:
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
此解决方案的问题在于,当我发送SIGINT(Ctrl + C)时,通常在退出“tail -f”时执行的操作会在后台留下一个孤儿。我已经用“trap”搜索了解决方案,但是我做得不好,而且它似乎无法与“tail -f”之类的永恒过程一起使用。
我很高兴在这里提出您的想法,并开始进行高级bash编程。
最佳答案
只要脚本退出,您就可以trap
,然后终止该进程。但是,您不需要-9
即可杀死自己的tail
,这太过分了。
您也可以使用inotify
告诉您目录中什么时候发生,而不是休眠和重新检查。这是一个基本的构建块。 inotify
有很多事件可以等待。如果文件已被移动/重命名,则可以添加检测,因此在这种情况下,您不必重新启动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
关于linux - BASH : How to make a script that make “tail -f” always logging the last file in a directory,直播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62884539/