-1

我正在尝试设置一个 inotifywait 脚本来执行此操作:

  • 第 1 步:创建目录,将文件放入其中,这会触发 inotifywatch 触发第 2 步
  • 第 2 步:30 分钟后,目录移动并创建符号链接回到旧的根目录

这是我到目前为止所拥有的,但它并不完全有效。它是从我在网上找到的不同示例中拼凑而成的。

inotify.sh:

#!/bin/sh

cd ~/automove/old/
inotifywait -m -e close_write --format %w%f . | while IFS= read -r file; do
  echo $file
  sleep 15
  sh ~/automove/move.sh "$file" ~/automove/new/
done

移动.sh:

#!/bin/sh
original="$1" target="$2"
if [ -d "$target" ]; then
  target="$target/${original##*/}"
fi
mv -- "$original" "$target"
ln -s -- "$target" "$original"

我的问题如下:

  • 带有“撇号”的目录会被破坏。
  • 似乎 inotifywait 会在新的符号链接上被触发,从而创建一个疯狂的无限循环。
  • 如果一个目录触发了 inotifywait,然后它休眠了 15 秒(我将其设置为测试,实际上我想要 30 分钟),然后在原来的 15 秒结束之前出现另一个目录,它甚至不会开始第二个15 秒睡眠,直到第一个完成。

我需要为每个 inotifywait 匹配单独触发睡眠。谁能告诉我如何修改它以按照我需要的方式工作?

4

1 回答 1

0

用 not 开始你的脚本#!/bin/bash#!bin/sh确保你真的在使用 bash (我认为你的一些构造是特定于 bash 的)。您可能需要添加-ue以确保您的问题不是由静默失败的变量引用或命令引起的。

--

“损坏”的目录

您能否更具体地说明会发生什么?

--

“单独等待 15 秒”

您将输出管道inotifywait传输到一个while循环。管道的每一侧都是一个单独的过程。如果我理解正确,您希望循环继续下一次迭代而不等待,同时在执行其余语句之前分别等待 15 秒。

为此,您需要创建一个额外的进程来执行sleep以下语句。将循环内的语句括在括号内,并在右括号&后添加,如下所示:

{
  echo $file
  sleep 15
  sh ~/automove/move.sh "$file" ~/automove/new/
} &

您可以选择将这些语句放在一个函数中,并从循环内部调用该函数,后跟相同的&字符(它在后台执行的单独进程中执行语句)。

您可能希望wait在脚本的末尾添加一条语句,以便它等待所有子进程结束,然后再将控制权交还给启动它的进程。

--

无限循环:我没有测试过,但inotifywait可能会在您创建符号链接时触发。你可能想让你的循环看起来像这样:

do
  if
    ! [ -d "$file" ] || [ -L "$file" ]
  then
    continue
  fi
  (followed by the code suggested above...)
done

当目标文件不是目录时,此代码将绕过循环内的其余代码并跳到下一次迭代。

注意:[ -d "$file" ]在测试指向目录的符号链接时似乎返回 0 (true),因此我建议的测试确保文件是目录而不是符号链接。

--

请注意,我尚未测试您的代码或我建议的代码。

我希望这有帮助!

于 2017-01-15T21:23:37.277 回答