linux - BASH : How to make a script that make “tail -f” always logging the last file in a directory,直播

标签 linux bash multithreading

我基本上是想使我的其他脚本的调试更容易。
(Centos 7.6)
我需要做的是一个脚本:

  • tail -f目录
  • 中的最后一个文件条目
  • 如果新文件出现在此目录中,它将记录此新文件,顺利
  • 如果我发送SIGINT(Ctrl + C),则不会离开孤儿
  • ,具有尽可能少的附加组件,以实现最大的可移植性

  • 这是我不工作的解决方案:
    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/

    相关文章:

    Java:线程:添加具有 ID 的元素以从不同线程列出

    linux - 未找到 jessie debian 的规范源

    Bash语法错误

    arrays - awk 中的算术运算符无效

    ios - 在不同线程上调用的类的实例方法可以使用类的属性吗?

    java - Java中如何终止这样的线程

    将函数从用户空间复制到内核并执行

    php - 让 Linux 用户能够包含 PHP 代码但不能查看它?

    linux - 性能工具 - 前 n 条指令的配置文件

    bash - 检查蚊子健康的脚本