需要帮助修复此inotifywait bash脚本

时间:2017-01-15 18:14:32

标签: bash inotifywait

我尝试设置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

move.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匹配单独触发睡眠。 谁能告诉我如何修改它以我需要的方式工作?

1 个答案:

答案 0 :(得分:0)

使用#!/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),因此我建议的测试确保该文件是目录而不是符号链接。

-

请注意我没有测试您的代码或我建议的代码。

我希望这有帮助!