6

我有 inotifwait 的 shell 脚本设置如下:

inotifywait -r  -e close_write,moved_to  -m "<path>/upload" --format '%f##@@##%e##@@##%w'

有一些 docx 文件驻留在监视目录中,一些脚本通过以下命令将 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/

这里还有什么问题?

问候

4

2 回答 2

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 建议的解决方法。

于 2017-10-07T19:18:31.857 回答
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}"

在您的实际脚本中,您将禁用echoin if,这仅用于演示目的

于 2017-10-07T09:41:52.330 回答