简体   繁体   English

BASH:如何制作一个脚本,使“tail -f”始终记录目录中的最后一个文件,实时

[英]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:我需要的是一个脚本:

  1. tail -f the last file entry in a directory tail -f 目录中的最后一个文件条目
  2. if a new file appears in this directory, it logs this new file, smoothly如果这个目录中出现了一个新文件,它会顺利记录这个新文件
  3. if I send a SIGINT (Ctrl+C), it doesn't leave orphans如果我发送 SIGINT (Ctrl+C),它不会留下孤儿
  4. with the less possible add-ons for the maximum portability尽可能少的附加组件以实现最大的便携性

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM