【问题标题】:How to check if file size is not incrementing ,if not then kill the $$ of script如何检查文件大小是否没有增加,如果没有,则终止脚本的 $$
【发布时间】:2015-12-01 09:07:45
【问题描述】:

我正在尝试找出一种方法来监控我从脚本中转储的文件。如果在子文件中没有看到增量,则终止我的脚本。

我这样做是为了在不需要时释放资源。这是我的想法,但我认为我的方法会增加 CPU 的负担。任何人都可以建议更有效的方法吗?

下面的脚本假设每 15 秒轮询一次并收集同一文件的两个文件大小,如果两个样本的大小相同则退出。

checkUsage() {
  while true; do
    sleep 15
    fileSize=$(stat -c%s $1)

    sleep 10;
    fileSizeNew=$(stat -c%s $1)

    if [ "$fileSize" == "$fileSizeNew" ]; then
      echo -e  "[Error]: No activity noted on this window from 5 sec. Exiting..."
      kill -9 $$
    fi
  done
}

我打算这样称呼它(在后台):

checkUsage /var/log/messages &

如果有人建议如何监视 tail 命令,并且如果 tail 上没有任何打印内容,我也可以得到解决方案,然后退出。不知道为什么人们会感到困惑。这个问题的最终目标是检查某个文件是否在最后 15 秒内被编辑。如果不退出或抛出一些错误。

我已经通过上面的脚本实现了这个,但我不知道这是否是实现这个的最聪明的方法。如果有任何替代方法或更好的方法,我已经问过这个问题以了解其他人的观点。

【问题讨论】:

  • 最终目标是什么?听起来像是 XY 问题...
  • 最终目标是确保如果 /var/log/messages 在 15 秒内没有增加其大小,则终止我的脚本。
  • 你认为负担在哪里? sleep 不会消耗任何资源,并且两个 stat 调用对于您要完成的事情很难避免。你在哪里看到问题?一个解决方案允许使用多少资源才能被接受?
  • 循环总计 25 秒,消息显示 5 秒。也许更仔细地考虑时间应该是什么。
  • 不妨用 stat 检查 mtime。从逻辑上讲,检查文件大小是可以的,但这只是说事情没有改变的一种奇怪方式,而 mtime 则更直接。

标签: linux bash shell unix tail


【解决方案1】:

我会根据文件修改时间而不是大小来检查,所以像这样(未经测试的代码):

checkUsage() {
  while true; do
    # Test if file mtime is 'second arg' seconds older than date, default to 10 seconds
    if [ $(( $(date +"%s") - $(stat -c%Y /var/log/message) )) -gt ${2-10} ]; then
      echo -e  "[Error]: No activity noted on this window from ${2-10} sec. Exiting..."
      return 1
    fi
    #Sleep 'first arg' second, 15 seconds by default
    sleep ${1-15}
  done
}

想法是将文件mtime与当前时间进行比较,如果大于第二个参数秒,则打印消息并返回。

然后我稍后会这样调用它(或者没有使用默认值的参数):

[ checkusage 20 10 ] || exit 1

当函数从它的无限循环返回时,它会以代码 1 退出脚本(只要文件被修改)

编辑:再读一遍,目标文件也可以是一个参数,以便更好地重用函数,留给读者作为练习。

【讨论】:

    【解决方案2】:

    如果在 Linux 上,在本地文件系统(Ext4、BTRFS、...)中 - 而不是网络文件系统 - 那么您可以考虑 inotify(7) 设施:当某些文件或目录更改或被访问时,可能会触发某些东西.

    特别是,你可能有一些通过incrontab(5) 文件的 incron 工作;也许它可以与其他工作沟通......

    PS。我不确定你真正想做什么......

    【讨论】:

    • 本题的最终目标是,检查某个文件是否在最近 15 秒内被编辑。如果不退出或抛出一些错误。我已经通过上面的脚本实现了这一点,但我不知道这是否是实现这一目标的最聪明的方法。如果有任何替代方法或更好的方法,我已经问过这个问题以了解其他人的观点。
    • 你为什么要这样做?您要解决的问题是什么?
    • 我正在尝试检查在过去 15 秒内某个 X 文件中是否有任何更改。如果有任何机会,请忽略并在一段时间后继续检查。但是,如果文件 X 中没有任何更改,则退出或抛出错误。
    【解决方案3】:

    我想一个外部程序正在修改/var/log/messages

    如果是这种情况,下面是我的脚本(对你的稍作改动)

    #Bash script to monitor changes to file
    #!/bin/bash
    checkUsage() # Note that U is in caps
    {
    while true
    do
            sleep 15
            fileSize=$(stat -c%s $1)
            sleep 10;
            fileSizeNew=$(stat -c%s $1)
    
            if [ "$fileSize" == "$fileSizeNew" ]
            then
               echo -e  "[Notice : ] no changes noted in $1 : gracefully exiting"
               exit # previously this was kill -9 $$
               # changing this to exit would end the program gracefully.
               # use kill -9  to kill a process which is not under your control.
               # kill -9 sends the SIGKILL signal.
            fi
    
    done
    }
    checkUsage $1 # I have added this to your script
    
    #End of the script
    

    将脚本保存为checkusage 并像这样运行它:

    ./checkusage /var/log/messages &
    

    编辑:

    由于您正在寻找更好的解决方案,我建议inotifywait,感谢其他回答者的建议。

    下面是我的代码:

    while inotifywait -t 10 -q -e modify $1 >/dev/null
    do
        sleep 15 # as you said the polling would happen in 15 seconds.
    done
    echo "Script exited gracefully : $1 has not been changed"
    

    以下是来自inotifywait manpage的详细信息

    -t , --timeout 如果在 秒内没有发生适当的事件,则退出。如果 为零(默认值), 无限期地等待一个事件。

    -e , --event 仅监听特定事件。可以监听的事件列在 EVENTS 部分。 可以多次指定此选项。如果省略,所有事件 被倾听。

    -q, --quiet 如果指定一次,程序将不那么冗长。具体来说,它不会说明它何时完成建立所有 通知手表。

    modify(Event) 被监视的文件或被监视目录中的文件被 写给。

    备注

    您可能必须先安装inotify-tools 才能使用inotifywait 命令。查看 Github 上的 inotify-tools 页面。

    【讨论】:

    • 这些更改非常次要...除了更改缩进和打印的消息之外,您还做了什么?为什么是kill 而不是exit
    • 事实上,我的意思是退出是优雅的,而 kill -9 是有力的。请查看编辑。
    • gracefully exitingkill -9哈哈哈
    • 您对编辑部分表示赞同。缺点是:1)需要额外的包/编译,这可能适合也可能不适合所有情况,2)不能在网络文件系统上工作。但这确实是一个不错的选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-20
    • 1970-01-01
    • 2017-07-13
    • 1970-01-01
    • 1970-01-01
    • 2018-05-11
    • 2018-04-25
    相关资源
    最近更新 更多