【问题标题】:Any script to notify when there is no write activity in folder当文件夹中没有写入活动时通知的任何脚本
【发布时间】:2015-05-21 12:33:36
【问题描述】:

我想拿出一个很好的和当没有发生过的文件夹中的任何写活动我很喜欢看检测简便的方法。 P>

基本上,我想有是这样的: P>

#!/bin/sh

# colored red text (error)
function errorMsg () {
  echo '\033[0;31m'"$1"'\033[0m'
}

# check for folder to monitor argument
if [ "$#" -ne 1 ]
then
  errorMsg "add experiment (folder) to monitor for activity!"
exit
fi

# time out time, 3 minutes
TIMEOUT_TIME=180
LAST_CHECKED=0

function refreshTimer () {
  # when called, check seconds since epoch
  CURRENT_TIME=date +%s

  if [ CURRENT_TIME - LAST_CHECKED > TIMEOUT_TIME ]
  then
    echo "file write activity halted!" | mail -s "trouble!" "user@provider.ext"
  fi

  LAST_CHECKED=date +%s
}

# set last checked to now.
LAST_CHECKED=date +%s
# start monitoring for file changes, and update timer when new files are being written.
fswatch -r ${1} | refreshTimer

但各种bash的魔术需要我想,因为fswatch是一个后台任务和其输出作为管道创建一个子外壳。 我也将是在一些需要定时逻辑... 我的想法是这样,其中的时间争论不断被添加的时候有活动的setTimeout的,但我不知道如何给它的所有写一个脚本。 P>

猛砸,Python和Ruby,任何可以使用的OSX自制安装是好的,但越简单越好(让我明白发生了什么)。 P>

【问题讨论】:

  • 您需要使用#!/bin/bash的hashbang的,或删除所有bash -only结构从你的脚本。 SPAN>
  • 请澄清你的问题是什么。我们不会开发整个脚本的你,和AFAIK软件建议是题外话。 SPAN>
  • @ chepner我写的东西把我的头顶部,使用一些部件来自不同的脚本,但是,是的,你是对的:) @ l0b0,我不知道你有什么不明白。我使用的情况是,我运行模拟,他们把结果的文件夹(即写操作)英寸这个我可以看有(使用自制安装)fswatch。不过,我想知道,当没有发生过的,而任何写入活动(这表明事情错了)。我甚至试图表明我想要的东西通过创建一个存根脚本..我没有问关于软件的建议。我指出,任何解决办法是罚款。 SPAN>

标签: macos bash terminal fswatch


【解决方案1】:

尝试以下操作 - 请注意,它需要 bash

#!/usr/bin/env bash

# colored red text (error)
function errorMsg () {
  printf '\033[0;31m%s\033[0m\n' "$*" >&2
}

# check for folder to monitor argument
if [[ $# -ne 1 ]]
then
  errorMsg "add experiment (folder) to monitor for activity!"
  exit 2
fi

# time-out: 3 minutes
TIMEOUT_TIME=180

# Read fswatch output as long as it is
# within the timeout value; every change reported
# resets the timer.
while IFS= read -t $TIMEOUT_TIME -d '' -r file; do 
  echo "changed: [$file]"
done < <(fswatch -r -0 "${1}")

# Getting here means that read timed out.
echo "file write activity halted!" | mail -s "trouble!" "user@provider.ext"
  • fswatch 无限期将行输出到标准输出,必须逐行读取这些行以对新输出及时采取行动。
  • fswatch -0 以 NUL(零字节)终止行,read 然后通过将行分隔符(分隔符)设置为空字符串 (-d '') 将其读取为 1。
  • &lt; &lt;(fswatch -r -0 "${1}") 通过标准输入&lt;while 循环提供输入,其中read 一次使用一个以NUL 终止的行的标准输入。
    • &lt;(fswatch -r -0 "${1}") 是一个process substitution,它从fswatch -r -0 "${1}"(监视文件夹${1} 的子树(-r)产生的输出中形成一个“临时文件”(技术上是一个FIFO 或命名文件描述符)用于文件更改,并报告每个都以 NUL (-0)) 终止。
    • 由于fswatch 命令无限期运行,“临时文件”将继续提供输入,但通常只是间歇性的,具体取决于文件系统活动。
  • 每当read 命令在超时期限 (-t $TIMEOUT_TIME) 内收到新行时,它成功地终止(退出代码 0),导致循环体被执行,然后read 将被再次调用
    • 因此,每当收到一行时,超时期限就会有效地重置,因为新的read 调用会在超时期限内重新开始。
    • 相比之下,如果在接收到另一行之前超时期限到期,read 将终止不成功 - 非零 退出代码指示失败,这会导致while 循环终止。
  • 因此,只有在read 命令超时时,才会到达循环之后的代码。

至于您的原始代码

注意:在shellecheck.net的帮助下可以检测到一些讨论的问题

  • echo '\033[0;31m'"$1"'\033[0m'
    • 在解释转义序列时,printf 是更好的选择,因为 echo 的行为因 shell 和平台而异;例如,使用 bash 运行您的脚本将不会解释它们(除非您还添加了 -e 选项)。
  • function refreshTimer ()
    • function 语法是非标准的(不符合 POSIX 标准),因此您不应该将它与 sh shebang 行一起使用(这就是 chepner 在他的评论中的意思)。在 OSX 上,您可以摆脱它,因为 bash 充当 sh 并且 大多数 bashism 在以 sh 运行时仍然可用,但它不适用于其他系统。如果您知道无论如何都会使用bash,最好使用bash shebang 行。
  • CURRENT_TIME=date +%s
    • 您不能通过简单地将命令按原样放在分配的 RHS 上来将命令的输出分配给变量;相反,你需要一个command substitution;在手头的情况下:CURRENT_TIME=$(date +%s)(带有反引号的旧语法 - CURRENT_TIME=`date +%s` - 也可以,但有缺点)。
  • [ CURRENT_TIME - LAST_CHECKED &gt; TIMEOUT_TIME ]

    • &gt;[ ... ] 和bash 的[[ ... ]] 条件是词法 比较,变量名必须是$-前缀;您必须在语法中使用 算术 条件:(( CURRENT_TIME - LAST_CHECKED &gt; TIMEOUT_TIME ))
    • 顺便说一句,在 shell 编程中better not to use all-uppercase variable names 更好。
  • fswatch -r ${1} | refreshTimer

    • refreshTimer 在管道填满之前不会被调用(您无法预测的时间),因为您没有尝试逐行读取
    • 即使你解决了这个问题,refreshTimer 中的变量也不会被保留,因为refreshTimer 每次都在新的子shell 中运行,因为使用了管道 (@987654375 @)。在bash 中,这个问题经常通过process substitution (&lt;(...)) 提供输入来解决,您可以在我上面的代码中看到它的实际效果。

【讨论】:

  • 这似乎正是我想要的,但我没有看到计时器在哪里重置?你能详细说明一下吗?谢谢!
  • 非常感谢@mklement0 的详尽解释,以及关于我非常糟糕的 shell 示例脚本的注意事项。我仍然需要习惯 while...done 语法,尽管我了解脚本的作用。这正是我想要的!如果我可以 +4 这个答案,我会这样做,以获得详尽的解释和有用的链接(共 4 个)。
  • @MichaelTrouw:我很高兴;我很高兴它有帮助。我已经重写了关于循环的解释——希望现在更清楚了。
  • 是的,现在我完全明白了,这就是我认为它会工作的方式,为 while 循环提供输入是我以前从未见过的,但这一切都很有意义!
猜你喜欢
  • 2016-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多