更新

更新

当存在来自不同来源的两个文件时,我需要启动一个命令。每个文件可能在不同的时间到达,但我希望在收到两个文件时触发命令。我尝试使用 incrond 来执行此操作,观察两个目录中的 IN_CLOSE_WRITE 和 IN_MOVED_TO。

/dir/path1 IN_CLOSE_WRITE,IN_MOVED_TO command
/dir/path2 IN_CLOSE_WRITE,IN_MOVED_TO command

问题是:当第一个监视触发后,如何等待第二个监视?

例如:

时间:12:05 UTC - 文件1 到达路径1 命令正在等待路径2 监视

时间:12:09 UTC - 文件2 到达路径2 命令启动

该命令是用 Go 编码的,但我找不到任何能帮助我的东西。

更具体地说,该系统的工作原理如下:有两个远程服务器以 6 小时为周期,以相同的周期在 pcap 中记录数据。它们记录相同的信息,但来自不同的 VLAN。记录完成后,它们将上传到主服务器的两个不同目录中。需要上传两个记录才能进行比较和混合它们,丢弃重复的数据包。记录并不总是以相同的顺序上传,也不会同时到达。这取决于远程服务器和主服务器之间的通信。

文件名始终是相同的模式:_yyyymmddTHHMMSS.pcap。例如,文件开始录制 2020-10-15 18:01:00:

文件1:vlan1_20201015T180100.pcap

文件2:vlan2_20201015T180100.pcap

我正在寻找与 incrond 和 bash 相关的解决方案或 Go 命令内的解决方案。解决方案或线索,因为我目前处于停滞状态。

答案1

我会创建一个由 incrond 调用的包装脚本,类似

if [ -f /dir/path1 -a -f /dir/path2 ]; then
  command
else
  echo "both files don't exist yet"
fi

每次文件触发 IN_CLOSE_WRITE 或 IN_MOVED_TO 时都会运行此操作,但只有当两个文件都存在时才会运行。

更新

根据评论,似乎有必要跟踪上传文件的完成状态。(我没有测试以下内容)这个想法是记录上传文件的完成情况,并且

#!/bin/bash

# $@ set to event filename by incrond
filepath=$@

# this assumes both files are in the same directory, otherwise you would
# have to do some logic which switches directories as well as filename

# check file matches pattern
if [[ "${filepath}" =~ vlan.*\.pcap$ ]]; then

  # mark current file as completed
  if [ ! -f "${filepath}.complete" ]; then
    touch "${filepath}.complete"
  fi

  filename=$(basename ${filepath})
  dirname=$(dirname ${filepath})

  # find other filename by toggling vlan number
  vlan_num=${filename:4:1}
  [[ "${vlan_num}" == "1" ]] && vlan_alt=2 || vlan_alt=1
  # construct the other filename
  other_file=${dirname}$/{filename:0:4}${vlan_alt}${filename:5}
  echo $other_file;

  # see if other filename completion file exists
  if [ -f "${other_file}.complete" ]; then
    command
  else
    # other file not uploaded yet
    echo "completion file for both files not exists"
  fi

else
  echo "file didn't match pattern"

fi

答案2

另一个解决方法是使用 lsof。此解决方案必须以 root 身份运行。

root 密码

/path/to/vlan1  IN_CLOSE_WRITE,IN_MOVED_TO  /usr/local/bin/monitor.sh $@/$# /path/to/vlan2
/path/to/vlan2  IN_CLOSE_WRITE,IN_MOVED_TO   /usr/local/bin/monitor.sh $@/$# /path/to/vlan1

包装脚本

#!/bin/bash
# monitor.sh
FILE_FINISHED=$1
FIND_PATH=$2

f=`basename $FILE_FINISHED`

FILE2=`ls $FIND_PATH/*${f:11:13}*`
STATUS=$?
if [ $STATUS -eq 0  ]
then
    lsof $FILE2 > /dev/null 2>&1
    STATUS=$?
    if [ $STATUS -ne 0 ]
    then
        echo "Command"
    else
        echo "Still uploading"
    fi
else
    echo "File not exist"
fi

相关内容