经过一番谷歌搜索,我发现entr
实用程序来运行文件更新命令。我可以让它工作,但不幸的是,我无法退出它。
关于它的文献并不多,对我来说也相当模糊。我需要一种行为,比如
- 检测文件变化
- 运行我的命令(在调用者脚本中设置 VAR)
- 出口
但不确定如何实现这一点。调用entr
似乎是一个无限循环,它无休止地运行。
很奇怪我找不到任何类似的用例。(https://github.com/eradman/entr)
我应该开始使用inotifywait
inotify-tools 包吗?
答案1
感谢@Kamil Maciorowski 的详细回答。
由于我已经在处理临时文件,因此我不会费心为entr
子进程创建另一个临时文件来存储它的值。
虽然entr
看起来像是一个很酷的小工具,但我还是选择了inotifywait
:
inotifywait -q -e close_write $buff_file_path |
while read -r filename event; do
:
done
result=$(cat $buff_file_path)
当事件发生时,它将退出。我基本上只是监视文件,并且只在文件更新时读取它。
我对问题/期望结果的初步描述有点模糊,我必须努力写出像样的问题。
感谢那些善良的人们这线。
答案2
正式说明
您的明确问题是:
我应该开始使用
inotifywait
inotify-tools 包吗?
我无法回答这个问题。“我应该吗?”的答案通常都是基于个人观点的。我认为隐含的问题是“我如何才能从entr
脚本中退出?”。这就是下面要回答的问题。
解决方案
以下命令:
entr -p sh -c 'kill -s INT "$PPID"; actual command(s)'
将(在被触发时)生成entr
一个 shell,该 shell 将杀死其父级(即entr
),然后执行actual command(s)
。
笔记
如果没有,
-p
entr
则会立即执行sh
并立即被杀死。您需要-p
。来自man 1 entr
:-p
推迟实用程序的第一次执行,直到文件被修改。entr
将要执行的命令(可执行文件 + 参数)作为其自己的单独参数。语法如下:entr echo "$var"
完全没问题。但是对于
sh -c
你来说外壳代码,一个字符串,将是解释由 shell 解析。我们的actual command(s)
将由 shell 解析。如果您需要外壳扩展任何内容并传递给内壳,请不要这样做:entr -p sh -c ‘kill -s INT “$PPID”;’” 回显 $var”或类似的东西。为了安全地执行此操作,请制作 shell 代码(的选项参数
sh -c
)静止的并使用位置参数传递变量值。例如:entr -p sh -c 'kill -s INT "$PPID"; echo "$1"' sh "$var"
这里,即使
$var
扩展为; rogue code
、'; rogue code
或'$(rogue code)
其他任何内容,也无法破坏实际的 shell 代码。(比较“永远不要嵌入
{}
shell 代码”,基本上是同一个问题。)您的目标是“在调用者脚本中设置 VAR”。如果没有调试器,只有解释脚本的 shell 才能更改其自身的变量。在 下运行的命令
entr
无法执行此操作。您可以捕获其输出或将其写入文件,然后让 shell 读取该文件。查看此问题的答案:从 Linux 子 shell 捕获特定的环境变量。