简体   繁体   English

用于监视新文件目录的bash脚本

[英]bash script which watches directory for new files

It's important to note immediately there are many variations of the 'script to watch a directory' I realize inotify-tools would be ideal however this particular script is being used to monitor a vboxsf filesystem which unfortunately doesn't forward filesystem notifications. 重要的是要注意立即有很多变体的'脚本来观看目录'我意识到inotify-tools是理想的,但是这个特殊的脚本被用来监视vboxsf文件系统,遗憾的是它不转发文件系统通知。 This script is a hack to refresh a file so a separate running daemon will notice it. 这个脚本是一个刷新文件的黑客,所以一个单独的运行守护进程会注意到它。

The script below is a compromise. 下面的脚本是妥协。 I spent a long time dealing with various issues 我花了很长时间处理各种问题

  1. the correct find args 正确的find args
  2. the find path and find路径和
  3. the timing for touching the found file. 触摸找到的文件的时间。

The objective is to identify the new file, touch it so the separate running daemon notices it and subsequently processes it. 目标是识别新文件,触摸它,以便单独的运行守护程序注意到它并随后处理它。 The problem is, well, it gobbles cpu and presumably from the find. 问题是,它吞噬了cpu并且可能来自发现。 I'd like help in finding a more efficient way of doing this. 我想帮助找到一种更有效的方法。

Although not necessary, but to fully test, one would need a mounted vboxsf filesystem with inotifywait running like so inotifywait -m /watches/watchdir -e attrib 虽然没有必要,但要完全测试,需要一个已安装的vboxsf文件系统,其中inotifywait运行如此inotifywait -m /watches/watchdir -e attrib

File creation on the host side will not result in an ATTRIB notification on the guest side until the file is somehow refreshed -- in which case this hack uses ' touch ' 在文件以某种方式刷新之前,主机端的文件创建不会在客户端产生ATTRIB通知 - 在这种情况下,此hack使用' touch '

thedir=/watches/watchdir

touch_me() {
    if [ "${newbie}" ]; then
 #  echo "got this: ${newbie}"
    touch -d '-120 seconds' "${newbie}"
    fi
}

while true
do
    newbie=`find $thedir/* -type f -mmin 0.1 2>/dev/null`
    touch_me
done

The filesystem's type at host side is not vboxsf , I believe. 我相信,主机端的文件系统类型不是vboxsf

As a consequence, inotify-tools can be used at the host server side, right? 因此, inotify-tools可以在主机服务器端使用,对吗?

It is assumed that a touch on the newly created file from host server side has no effect, rigth? 假设从主机服务器端touch新创建的文件没有效果,那么?

When new files are created at host server side, inotify-tools could use VBoXManage to execute a touch command into the guest, eg: 在主机服务器端创建新文件时, inotify-tools可以使用VBoXManage对guest VBoXManage执行touch命令,例如:

$ VBoxManage guestcontrol execute vmname /usr/bin/touch --username root --password 'changeme' --arguments "-d '-120 seconds' /watches/watchdir/${newbie}"

What do you think? 你怎么看?

Otherwise your script is ok, but it is using polling. 否则你的脚本没问题,但它正在使用轮询。 So maybe a sleep is mandatory in such situation, with the risk to miss some of the newly created files... 因此,在这种情况下可能需要sleep ,有可能错过一些新创建的文件......

a tool like sysdig may be helpful. sysdig这样的工具可能会有所帮助。 For example, the following command show every file open that happens in /tmp: 例如,以下命令显示/ tmp中发生的每个文件打开:

sysdig evt.type=open and fd.name contains /tmp

This tool is very complex yet powerful, and by reading its manual you may find a valid solution to your problem. 此工具非常复杂但功能强大,通过阅读其手册,您可以找到解决问题的有效方法。

the loop is running continually without the need to do so 循环不断运行而不需要这样做

find $thedir/* -type f -mmin 0.1

will find files changed no more the 6 seconds ago (and no more then 55 seconds in the future but unlikely to occur naturally). 会在6秒前发现文件不再发生变化(未来不会超过55秒但不太可能自然发生)。 Supposing find runs in less the a second (unless you have thousands of files) you might like to insert a sleep 5 in the loop. 假设find运行的时间少于一秒(除非你有数千个文件),你可能想在循环中插入一个sleep 5。 Another thing is why do you put the time back 2 minutes on the recently changed files that you find ... surely anything that has not been changed for 2 minutes is in the same condition. 另一件事是你为什么要把时间花在2分钟后才能找到你发现的最近更改的文件...当然,任何在2分钟内没有改变的东西都处于相同的状态。 Would in not be a better option to mark the file with a rarely used attribute like 'no dump' so that the other demon is not going to unintentionally on files that look like they were touched by the script but were not ? 用一个很少使用的属性(比如'no dump')来标记文件是不是更好的选择,这样另一个恶魔就不会无意中看到那些看起来像是被脚本触及的文件但不是?

Rather then looping intensively with find would it be an option to do something like this (leaving the touch_me to to the -2min for the other deamon to detect): 而不是使用find进行密集循环,可以选择执行类似这样的操作(将touch_me保留到-2min,以便其他守护进程检测):

touch_me() {
  #  echo "got this: $1"
  touch -d '-120 seconds' $1
}

touch /tmp/file.ref
while true
do
  for FILE in $thedir/*
  do
    [ $FILE -nt /tmp/file.ref ] && touch_me $FILE
  done
  touch /tmp/file.ref
  sleep 60
done

This way each iteration of the while will look for files that have been modified after the previous iteration. 这样,while的每次迭代都将查找在上一次迭代之后已修改的文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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