多个 'find' 一次用于观察者 - 只执行第一个

Multiple 'find' for watchers at once - only executes first one

我正在尝试 运行 一个脚本,它将监视不同的文件夹和文件,如果它们发生变化,则执行命令。其中一个文件夹路径接受一个动态变量,该变量将根据 运行 在 CLI 中运行脚本时输入的内容而改变,而另一个则不会改变。

但是,根据文件路径,需要采取不同的操作。

#!/usr/bin/env bash

THEME=

while true;
do
  echo "inside find"
    find code/themes/$THEME/src -name '*.html' -o -name '*.ts' -o -name '*.scss' | entr -d rsync -avh code/themes/$THEME/*  ./
    find code/base/src -name '*.html' -o -name '*.ts' -o -name '*.scss' | entr -d rsync -avh code/base/*  ./
done

当我 运行 脚本时发生的事情是它只执行并将监视放在第一个查找上(在上面粘贴的代码示例中,仅动态路径)。

目前我的问题是:

我怎样才能同时到达 运行?或者,如何将所有内容写在一行中?

此外,我以前从未编写过脚本或使用过 bash,所以如果您对重构有任何建议或能够帮助解决我的问题,请温和地进行技术解释。

我的主要目标是:

  1. 我想监视路径中的任何变化 code/themes/$THEME/src
  2. 我想监视路径中的任何变化 code/base/src
  3. 我希望两个观察者同时 运行ning

如果您的任务只是确保两个(或 1 个 + 多个主题)目录的下游副本始终是最新的,则 cron 作业每隔 同步一次它们n 分钟可能是最简单和最可靠的解决方案。 cron 具有 per-minute 粒度,但对于您的用例来说,每五分钟一次可能就足够了。 rsync 按照设计不会复制已经是最新的文件,因此在 no-op 情况下执行起来应该相当快。

* * * * * bin/rsyncthemes

(这是每分钟一次;在 Linux 上,您可以在第一个字段中说 */5 到每 5 分钟 运行,但这不适用于所有 cron 方言。) ... 其中 rsyncthemes 包含类似

的内容
#!/bin/sh
# cron jobs always start in your home directory,
# but you want to put an absolute path here
# to run this in the directory where you want rsync to copy these files
cd somewhere

for dir in code/themes/one \
    code/themes/other \
    code/base
do
    rsync -avh "$dir"/*  ./
done

显然这需要标记为可执行 (chmod a+x rsyncthemes) 并保存在我们在 cron 作业中指定的目录中(即 bin 在您的主目录中)。

如果您执意使用 entr 来避免不必要地 运行 宁 rsync,不过,我猜您想要类似

的东西
for dir in code/themes/one \
    code/themes/other \
    code/base
do
    while true; do
        find "$dir"/src -name '*.html' -o -name '*.ts' -o -name '*.scss' |
        entr -d rsync -avh "$dir"/*  ./
    done & # <-- run each loop as a background job
done

更详细地说,我们将 运行 三个 while true 循环作为后台作业,一个用于 for 循环中列举的每个目录。它们 运行ning 与您的交互式 shell 并行,并且会在您注销时停止 运行ning(除非您单独将它们设置为保持 运行 类似 nohup). & 运算符是 运行 后台的东西,将它放在 while 循环的 done 语句之后使其适用于整个循环。

我猜您可能需要使用 entr -n 才能让作业在后台 运行。

rsync 命令中的通配符被 shell 扩展,因此您可能需要重构它以不使用通配符,或者仅在 find 之后评估通配符完成,如果您希望新文件偶尔会出现在这些目录中。 (如果我正确阅读 entr 手册页,引用整个 rsync 命令并用 entr -s 传递它应该可以轻松完成此操作。)