监控共享文件夹中新文件的脚本(windows 主机,linux 来宾)

Fre*_*ger 6 linux virtual-machine

我需要监视共享文件夹,在这种特定情况下,主机是 windows,来宾是 Ubuntu linux,用于新文件或已更改的文件。理想情况下,解决方案应该独立于主机或将文件放入共享目录的机器。新文件将成为不同进程的输入。

如果文件由主机创建并放入共享文件夹,则 inotifywait 工具集不会检测新文件。

我有哪些选择?

Pau*_*din 5

您需要轮询文件更改的东西,因为如果文件在 Windows 端被修改,Linux 内核不会知道它。有一些现有的应用程序可以帮助解决这个问题,例如 Guard:http : //guardgem.org/

根据您的确切需求,您可以只watch列出文件列表(将 n 秒调整为任何合适的值):

watch --differences -n 10 ls -l </path/to/shared/dir>
Run Code Online (Sandbox Code Playgroud)


mr.*_*tic 1

您也许可以使用早于dnotifyinotify的轮询工具之一:gaminfam,以及类似fileschanged之类的inotifywaitCLI 工具。gamin 和 fam 项目是相关的,并且都相当古老(尽管 gamin 稍微不那么古老)。

对于简单且可移植的任务,我通过 cron 使用了类似的东西

if mkdir /var/lock/mylock; then
  ( cd /mnt/mypath; find . -type f -mmin +2 ) | myprocess
  rmdir /var/lock/mylock
else
  logger -p local0.notice "mylock found, skipping run"
fi
Run Code Online (Sandbox Code Playgroud)

这使用原始锁定和 GNUfind条件来仅查找于两分钟的文件,因此我可以确定文件已完全写入。就我而言myprocessrsync --remove-source-files --files-from=-文件一旦被处理就会被删除。

这种方法还允许您使用find -print0//来处理麻烦的文件名。xargs -0rsync -0

如果您必须将所有(旧的和新的)文件保留在同一目录层次结构中,那么构建目录列表快照并比较它们可能也适合您:

if mkdir /var/lock/mylock; then
  ( 
    export LC_COLLATE=C  # for sort
    cd /mnt/mypath
    find . -type f -a \! -name ".dirlist.*" -printf '%p\0' | 
      while read -d '' file; do
        printf "%q\n" "${file}"  
      done > .dirlist.new
    [[ -f  .dirlist.old ]] && {
      comm -13 <(sort .dirlist.old) <(sort .dirlist.new) |
        while read -r file; do
          myprocess "${file}"
        done
    }
    mv .dirlist.new .dirlist.new
  )
  rmdir /var/lock/mylock
else
  logger -p local0.notice "mylock found, skipping run"
fi
Run Code Online (Sandbox Code Playgroud)

这个bash脚本:

  1. 用于find -printf打印 \0 (nul) 分隔的文件列表
  2. 用于read -d ''处理该列表,并printf %q在必要时转义文件名
  3. 比较新的和以前的 .dirlist 文件
  4. 调用myprocess每个新文件(安全引用)

(处理修改后的find ... -printf '%p\0%s %Ts\0'文件也需要稍微多一些努力,可以使用双行格式,并对while循环进行相关更改。)