0

I have this code:

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

The problem is that my script read what inotifywait produce. So my question is: what is the proper way to run test_port.scm on each file change if that script read from stdin?

UPDATE:

So how this works look like this, I've made change it run the script to wait for input. but entering text don't work. And if I save again I've got:

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

my code look like this:

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

scheme code that read and print single line, the code is more complex under the hood, it's in fact Node.js + Readline that should read single line:

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();
            });
        });
    }),

I think that the issue is just with the while read x; that's why I've asked here.

UPDATE:

My actual issue is that I want to run script on each file change and the script need to read stdin, I actually don't care if it's inotifywait, but this is the only solution I've found that run on file change.

2
  • Please, add sample output of inotifywait when you write to the file – Gilles Quenot Jun 22 '20 at 20:59
  • @GillesQuenot I've updated the code it show how it work. – jcubic Jun 22 '20 at 21:08
3
inotifywait -m -e close_write src/lips.js ./test_port.scm |
    while read x; do
        ./test_port.scm </dev/tty
    done
0
4

The general way is to wrap your whole pipeline as a list, duplicate the file descriptor used as its standard input and redirect the standard input of the command in your loop's body to make it read from that new one:

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

This is basically equivalent to using /dev/tty, as Hauke Laging's answer does, but it also allows the outer standard input not to be a terminal.

Note that, however, this solution requires filenames not to contain newline characters: they would make the loop's body run more than once for each event (with a spurious value of the x variable). Depending on your use case, it may be fine for you to prevent inotifywait from printing filenames by means of its --format option.

2

Just found this at SuperUser How to execute a command whenever a file changes?

There is alternative call with:

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

Or, to make inotifywait print nothing:

while inotifywait -qq -e ...
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.