在脚本中使用 inotifywait -m 而不创建额外的进程?

Posted

技术标签:

【中文标题】在脚本中使用 inotifywait -m 而不创建额外的进程?【英文标题】:Use inotifywait -m in script without creating extra process? 【发布时间】:2016-07-09 01:36:01 【问题描述】:

我不确定这是否可行,但我经常这样想,并且一些解决方案让我感到惊讶。是否可以在不创建两个进程的情况下创建与以下脚本等效的脚本(在这种情况下,很明显,因为有管道,所以创建了两个进程):

#!/bin/bash

EVENTS="CREATE,CLOSE_WRITE,DELETE,MODIFY,MOVED_FROM,MOVED_TO"
inotifywait -e "$EVENTS" -m -r ~/Desktop/testing | \
  while true; do
    read TMP
    echo "$TMP" >> ~/Desktop/eventlog
  done

请注意,在 while 循环中,我确实希望能够访问该事件。

在我看来,管道是必要的,因为我们需要用一个进程写入并从另一个进程读取。不过说不定有什么诀窍呢?

【问题讨论】:

【参考方案1】:

bash 4.2 中,您可以设置lastpipe 选项以允许while 循环在当前shell 而不是单独的进程中运行。

shopt -s lastpipe
inotifywait -e "$EVENTS" -m -r ~/Desktop/testing |
  while true; do
    read TMP
    echo "$TMP" >> ~/Desktop/eventlog
  done

(您不需要在| 之后显式续行,因为bash 知道行不能以该字符结尾。)

【讨论】:

啊,是的,这就是我想要达到的目标。有趣的是,我想知道如何实现它。我猜他们不会创建一个新进程而是一个新线程?似乎一个人在写,一个人在读,肯定有两个“东西”。我猜有两个线程。 不,只是在新进程中运行第一个命令并在当前进程中运行循环,而不是分叉两个新进程并等待。【参考方案2】:

假设您希望避免使用辅助脚本以便在 for 循环中修改的变量在循环完成后不会丢失其值是否正确?

在这种情况下,您可以交换之类的东西

while read TMP; do
  echo "$TMP" >> ~/Desktop/eventlog
done < <(inotifywait -e "$EVENTS" -m -r ~/Desktop/testing)

但如果您担心代码流的灵活性 您可以重定向到文件句柄,然后随时从该句柄读取 如果您想让我找出示例,请在下面评论

如果是其他问题 - 请添加有关您实际想要做什么的详细信息

【讨论】:

感谢您的回答。我会研究它。很抱歉我的请求不够明确。我不希望从循环中运行两个进程。 chepner 有我希望的答案。亲切的问候。

以上是关于在脚本中使用 inotifywait -m 而不创建额外的进程?的主要内容,如果未能解决你的问题,请参考以下文章

使用 inotifywait 监视多个目录并运行脚本

通过 FTP 将文件添加到 git 存储库时,在脚本中使用 inotifywait 自动执行 git 提交

在运行脚本之前使用 inotifywait (或替代方法)等待 rsync 传输完成?

inotifywait 未在 bash 脚本中执行 while 循环

`inotifywait` 不会在带有 `-e delete_self` 的 bash 脚本中终止;但在交互式外壳中

bash 脚本 inotifywait 在继续之前等待文件完全写入