Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

entr can't be stopped #19

Closed
unphased opened this issue Jan 16, 2020 · 7 comments
Closed

entr can't be stopped #19

unphased opened this issue Jan 16, 2020 · 7 comments

Comments

@unphased
Copy link

unphased commented Jan 16, 2020

Just doing a simple test

while true; do ls test* | entr -d echo changed: /_; done

while in the directory ~/util on Ubuntu 18.04.

I did some testing to test if it picks up changes from new files i added with a name starting with "test". Then I added some directories using mkdir -p and saw that it did not watch files inside there (all what I expected)

The behavior is that when I press Ctrl+C it just prints changed: /home/slu/util/testfile and carries on merrily. First few times it did this spamming Ctrl+C worked fine. But now, for some reason, no amount of SIGINT will stop it, and neither does SIGKILL from htop stop it. pkill -9 -f entr isn't working either.

Version 4.4, built from source.

I'll need to kill the shell parent process to stop it. I was really hoping to finally find a robust inotify tool. Linux is so good at everything except monitoring its filesystem.

@unphased
Copy link
Author

unphased commented Jan 16, 2020

I killed it without killing the parent shell by:

  1. running sleep 2; mkdir b in a second terminal
  2. holding down ctrl+c in the terminal running entr. This seems to have allowed me to stop it before it sank its claws in deep enough. The enhanced keyboard repeat rate no doubt helped.

Also everything was tested from inside tmux.

I'd like to help fix it so let me know if you have trouble reproducing. It seems like there is some special signal behavior that entr is doing. What is the expected behavior when we send SIGINT to stop entr -d when it is inside an infinite shell loop?

@eradman
Copy link
Owner

eradman commented Jan 17, 2020

I don't think you're having trouble killing entr, instead it sounds likethe problem is that you are trying to stop the while loop which is rapidly starting processes

Try while sleep 1 ... instead

@eradman eradman closed this as completed Jan 29, 2020
@unphased
Copy link
Author

Yeah but why is while 1; do echo 'x'; done trivial to stop? The SIGINT handling is probably not doing something suitable for recommending running this in a loop like that without a sleep in it.

@eradman
Copy link
Owner

eradman commented Jan 29, 2020

In the example you just listed the while loop keeps control of STDIN, so Ctrl-C works. If you introduce a pipe you'll have the same problem:

while true; do ls ~/ | echo 'x'; done

In this case SIGINT is (usually) delivered to the child process after the |.

@unphased
Copy link
Author

unphased commented Jan 29, 2020

When I tested your snippet in both zsh and bash, the behavior is the same: I think all the programs making up the pipeline are supposed to receive the signal. There is no trouble with interrupting that snippet on the first ctrl+c keystroke. This is why I believe entr does something unusual with signal handling.

@robx
Copy link

robx commented Apr 7, 2020

I'm inclined to agree that something else is going on (though I doubt entr is to blame -- I've had these uninterruptible while loops before). I was thinking it's because the echo snippets might miss the signal because they're not ever really up and running for very long, but then why does this one interrupt nicely?

$ while true; do ls | sleep 1; done
^C
$

Edit: I should note that it appears that I run into this only when running this through a Makefile. I can't reproduce OP's problem.

@eradman
Copy link
Owner

eradman commented Apr 7, 2020

@robx the example you listed, sleep is a process that exists for a longer span of time. This is an important detail.

Control of the terminal is one factor (since it determines who receives SIGINT), but stopping loop is non-deterministic and unreliable any time the shell is rapidly running fork/exec. One reason for this is that SIGINT is sent to a process that no longer exists

Matt3o12 pushed a commit to Matt3o12/entr that referenced this issue Jan 15, 2022
* Add the ability to modify an existing client
* Update client page using Ajax
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants