当将docx转换为PDF时,inotifywait触发事件两次

7
我有一个带有inotifwait的shell脚本,如下所示:
inotifywait -r  -e close_write,moved_to  -m "<path>/upload" --format '%f##@@##%e##@@##%w'

有一些docx文件存放在被监视的目录中,然后通过以下命令将这些文件转换为PDF:

soffice --headless --convert-to pdf:writer_pdf_Export <path>/upload/somedoc.docx --outdir  <path>/upload/

生成PDF后,事件会被触发两次。具体日志如下:

somedoc.pdf##@@##CLOSE_WRITE,CLOSE##@@##<path>/upload/
somedoc.pdf##@@##CLOSE_WRITE,CLOSE##@@##<path>/upload/

还有什么问题需要解决?

祝好


我已经浏览了strace的结果,soffice.bin本身有两个close操作,第一个是将临时PDF结果文件复制到目标位置,第二个仅检查其状态,必须深入挖掘Java源代码。但这为什么会困扰你呢? - georgexsh
感谢@georgexsh的回复。实际上,这个触发器绑定了一些COPY-TO-CLOUD功能。因此,文件被复制了两次,并且同时进行了一些其他的后勤工作。 - Jatin Dhoot
@JatinDhoot 你在寻找什么样的答案? - Oleg Kuralenko
@ffeast - 我想让inotifywait仅在从soffice生成PDF时触发一次通知,而不是两次。谢谢。 - Jatin Dhoot
@JatinDhoot,如果文件本身似乎被写了两次,那么你不能没有包装代码来完成它。 - Oleg Kuralenko
2个回答

1
我不认为您可以完全控制外部程序。但是我猜测您正在使用此输出进行管道传输,然后将其输入到其他地方。在这种情况下,您可以避免连续发生几秒钟的事件。
因此,我们添加了%T--format--timefmt "%s"来获取纪元时间。以下是更新后的命令。
$ inotifywait -r  -e close_write,moved_to --timefmt "%s"  -m "/home/vagrant" --format '%f##@@##%e##@@##%w##T%T' -q | ./process.sh
test.txt##@@##CLOSE_WRITE,CLOSE##@@##/home/vagrant/
Skipping this event as it happend within 2 seconds. TimeDiff=2
test.txt##@@##CLOSE_WRITE,CLOSE##@@##/home/vagrant/

这是通过每秒多次使用touch test.txt完成的。如您所见,甚至跳过了第二个秒。 process.sh是一个简单的bash脚本。
#!/bin/bash

LAST_EVENT=
LAST_EVENT_TIME=0
while read line
do
  DEL="##T"
  EVENT_TIME=$(echo "$line" | awk -v delimeter="$DEL" '{split($0,a,delimeter)} END{print a[2]}')
  EVENT=$(echo "$line" | awk -v delimeter="$DEL" '{split($0,a,delimeter)} END{print a[1]}')
  TIME_DIFF=$(( $EVENT_TIME - $LAST_EVENT_TIME))
  if [[ "$EVENT" == "$LAST_EVENT" ]]; then
     if [[ $TIME_DIFF -gt 2 ]]; then
        echo "$EVENT"
     else
        echo "Skipping this event as it happend within 2 seconds. TimeDiff=$TIME_DIFF"
     fi
  else
    echo $EVENT
    LAST_EVENT_TIME=$EVENT_TIME
  fi
  LAST_EVENT=$EVENT
done < "${1:-/dev/stdin}"

在您实际的脚本中,您将在if语句中禁用echo,这只是演示目的。

感谢Tarun的努力。我会尝试一下并告诉你结果。问候 - Jatin Dhoot

1
它被触发两次,因为这是soffice在内部似乎的行为方式。也许有一天它会在单个运行期间写入10次并在这些写入之间执行sleep 2,我们的程序不能也不应该预测和依赖它。
因此,我会尝试从不同的角度解决问题 - 只需将转换后的文件放入临时目录,然后将其移到目标目录,就像这样: soffice --headless --convert-to pdf:writer_pdf_Export <path>/upload/somedoc.docx --outdir <path>/tempdir/ && mv <path>/tempdir/somedoc.pdf <path>/upload/ 并使用inotifywait如下:
inotifywait -r -e moved_to  -m "<path>/upload" --format '%f##@@##%e##@@##%w'

优点是您不再依赖于soffice的内部逻辑。如果无法调整生成pdf文件的脚本的行为,那么确实需要采用@Tarun建议的解决方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接