如何使用 inotifywait 调用从 stdin 读取的脚本

如何使用 inotifywait 调用从 stdin 读取的脚本

我有这个代码:

inotifywait -m -e close_write src/lips.js ./test_port.scm | \
while read x; do ./test_port.scm; done

问题是我的脚本读取了 inotifywait 产生的内容。所以我的问题是:如果该脚本从标准输入读取,那么在每个文件更改上运行 test_port.scm 的正确方法是什么?

更新

那么它的工作原理如下所示,我对其进行了更改,运行脚本以等待输入。但输入文字不起作用。如果我再次保存,我会得到:

./test_port.scm CLOSE_WRITE,CLOSE 
>>> ./test_port.scm CLOSE_WRITE,CLOSE 

我的代码如下所示:

(display (string-append ">>> " (read-line)))
(newline)

读取和打印单行的方案代码,代码在幕后更复杂,实际上是 Node.js + Readline 应该读取单行:

var interp = Interpreter('repl', {
    stdin: InputPort(function() {
        return new Promise(function(resolve) {
            rl = readline.createInterface({
                input: process.stdin,
                output: process.stdout
            });
            rl.question('', function(data) {
                resolve(data);
                rl.close();
            });
        });
    }),

我认为问题在于这就是while read x;我在这里问的原因。

更新:

我的实际问题是,我想在每个文件更改上运行脚本,并且脚本需要读取 stdin,实际上我不在乎它是否是 inotifywait,但这是我发现的在文件更改上运行的唯一解决方案。

答案1

一般方法是将整个管道包装为一个列表,复制用作其标准输入的文件描述符,并将命令的标准输入重定向到循环体中以使其从新管道中读取:

{
  inotifywait -m -e close_write src/lips.js ./test_port.scm |
    while read x; do
      ./test_port.scm 0<&3
    done
} 3<&0

这基本上相当于使用/dev/tty, 作为豪克·拉金的回答确实如此,但它也允许外部标准输入不是终端。

但请注意,此解决方案要求文件名不包含换行符:它们会使循环体针对每个事件运行多次(使用变量的虚假值x)。根据您的使用情况,您可以inotifywait通过其--format选项来阻止打印文件名。

答案2

inotifywait -m -e close_write src/lips.js ./test_port.scm |
    while read x; do
        ./test_port.scm </dev/tty
    done

答案3

刚刚在超级用户中找到了这个如何在文件更改时执行命令?

还有一个替代调用:

while inotifywait -q -e close_write myfile.py; do ./myfile.py; done

或者,不打印inotifywait任何内容:

while inotifywait -qq -e ...

相关内容