如何检查文件大小是否没有增加,如果没有则杀死脚本的 $$

How to check if file size is not incrementing ,if not then kill the $$ of script

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

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

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

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

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

    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 秒内被编辑过。如果不退出或抛出一些错误。

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

我想外部程序正在修改 /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 )
        sleep 10;
        fileSizeNew=$(stat -c%s )

        if [ "$fileSize" == "$fileSizeNew" ]
        then
           echo -e  "[Notice : ] no changes noted in  : 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  # I have added this to your script

#End of the script

将脚本另存为 checkusage 和 运行 如下:

./checkusage /var/log/messages &

编辑:

既然你正在寻找更好的解决方案,我会建议inotifywait,感谢其他回答者的建议。

下面是我的代码:

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

以下是 inotifywait manpage

中的详细信息

-t <seconds>, --timeout <seconds> Exit if an appropriate event has not occurred within <seconds> seconds. If <seconds> is zero (the default), wait indefinitely for an event.

-e <event>, --event <event> Listen for specific event(s) only. The events which can be listened for are listed in the EVENTS section. This option can be specified more than once. If omitted, all events are listened for.

-q, --quiet If specified once, the program will be less verbose. Specifically, it will not state when it has completed establishing all inotify watches.

modify(Event) A watched file or a file within a watched directory was written to.

备注

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

如果在 Linux 上,在本地文件系统(Ext4、BTRFS 等)中 - 而不是网络文件系统 - 那么你可以考虑 inotify(7) 设施:当某些文件或目录更改或被访问。

特别是,您可能会通过 incrontab(5) 文件进行一些 incron 作业;也许它可以与其他工作沟通......

PS。我不确定你到底想做什么...

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

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 与当前时间进行比较,如果它大于第二个参数秒,则打印消息并 return。

然后我以后会这样称呼它(或者没有参数使用默认值):

[ checkusage 20 10 ] || exit 1

这将以代码 1 退出脚本,就像函数 return 从它的无限循环中一样(只要文件被修改)

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