如何 运行 inotifywait 连续 运行 作为 cron 或 deamon?

How to run inotifywait continuously and run it as a cron or deamon?

我构建了一个 shell 脚本,它使用 inotifywait 自动检测特定目录中的文件更改。当一个新的 PDF 文件被放到目录中时,这个脚本应该关闭,然后它应该触发 ocropus-parser 对其执行一些命令。代码:

#!/bin/sh
inotifywait -m ~/Desktop/PdfFolder -e create -e moved_to |
while read path action file; do
    #echo "The file '$file' appeared in directory '$path' via '$action'"
    # Check if the file is a PDF or another file type.
    if [ $(head -c 4 "$file") = "%PDF" ]; then
        echo "PDF found - filename: " + $file
        python ocropus-parser.py $file
    else
        echo "NOT A PDF!"
fi
done

当我使用 ./filenotifier.sh 通过终端 运行 这个脚本时效果很好,但是当我重新启动我的 Linux (Ubuntu 14.04) 我的 shell 将不再 运行 并且在重启后不会重新启动。 我决定创建一个在引导时启动的初始化脚本(我认为)。我通过将文件 filenotifier.sh 复制到 init.d:

sudo cp ~/Desktop/PdfFolder/filenotifier.sh /etc/init.d/

然后我给了文件正确的权限:

sudo chmod 775 /etc/init.d/filenotifier.sh

最后我将文件添加到 update-rc.d:

sudo update-rc.d filenotifier.sh defaults

然而,当我重新启动并将 PDF 放入文件夹 ~/Desktop/PdfFolder 时,什么也不会发生,而且脚本似乎没有关闭。 我真的没有使用 init.dupdate-rc.ddeamon 的经验,所以我不确定哪里出了问题,也不确定这是否是一个好方法。

谢谢, 言特

  • 作为初始化脚本,您应该将 LSB header 添加到您的脚本中,如下所示:

    #!/bin/sh
    ### BEGIN INIT INFO
    # Provides:          filenotifier
    # Required-Start:    $remote_fs $syslog
    # Required-Stop:     $remote_fs $syslog
    # Default-Start:     2 3 4 5
    # Default-Stop:      0 1 6
    # Short-Description: Something
    # Description:       Something else
    ### END INIT INFO
    
    inotifywait -m ...
    

    这样,您可以确保您的脚本 运行 在所有挂载点都可用时运行(感谢 Required-Start: $remote_fs)。如果您的主目录不在根分区上,这是必不可少的。

  • 另一个问题是在您的初始化脚本中您使用的是 ~:

    inotifywait -m ~/Desktop/PdfFolder ...
    

    ~ 扩展到当前用户主目录。初始脚本是 运行 作为 root,所以它会扩展到 /root/Desktop/PdfFolder。使用 ~<username> 代替:

    inotifywait -m ~yenthe/Desktop/PdfFolder ...
    

    (假设您的用户名是yenthe。)

    或者在开始之前切换用户(使用 sudo)。

  • $file 是没有目录路径的基本名称。在你的命令中使用 "$path/$file"

    "$(head -c 4 "$path/$file")"
    python ocropus-parser.py "$path/$file"
    

    也许可以考虑使用 name 而不是 file,以避免混淆。

  • 如果事情不起作用,或者如果你想调查一些事情,记得使用 ps,像这样:

    ps -ef | grep inotifywait
    

    ps 会告诉您,例如,您的脚本是否 运行ning 以及 inotifywait 是否使用正确的参数启动。

  • 最后但同样重要的是:使用"$file",而不是$file;使用 "$(head -c 4 "$file")",而不是 $(head -c 4 "$file");使用 read -r,而不是 read。这些技巧可以让你以后省去很多麻烦!

为此目的,inotify 的开发者创建了 incron。它是一个类似 cron 的守护进程,它根据监视 file/directory 而不是时间事件的变化来执行脚本。