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

时间:2015-12-01 09:07:45

标签: linux bash shell unix tail

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

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

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

checkUsage /var/log/messages &

我计划将其称为以下(在后台):

{{1}}

我也可以得到解决方案,如果有人建议如何监控尾部命令,如果没有在尾部打印则退出。不确定为什么人们会混淆。这个问题的最终目标是,检查是否在最近15秒内编辑了某个文件。如果没有退出或抛出一些错误。

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

3 个答案:

答案 0 :(得分:2)

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

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

然后我会稍后再调用它(或者没有使用默认值的args):

[ checkusage 20 10 ] || exit 1

当函数从其无限循环返回时(只要文件被修改),将使用代码1退出脚本

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

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:0)

我想外部程序正在修改/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< seconds>, - timeout< seconds>如果在< seconds>内没有发生适当的事件,则退出秒。如果<秒>为零(默认值),   无限期地等待一个事件。

     

-e< event>, - event< event>仅收听特定事件。可以收听的事件列在EVENTS部分。   可以多次指定此选项。如果省略,则为所有事件   听了。

     

-q, - quiet如果指定一次,程序将不那么详细。具体而言,它不会说明何时完成所有建立   inotify手表。

     

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

备注

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