coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Feature request about "Tail -f": Gentle exit (not using CTRL+C)


From: Ingo Krabbe
Subject: Re: Feature request about "Tail -f": Gentle exit (not using CTRL+C)
Date: Sun, 21 Oct 2018 19:14:58 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1

Hi Brian,

you actually have many more options to leave a tail -f.

Typing CTRL+C in a terminal that runs a process means to send SIGINT to it (see signal(7)).

I could not find the exact documentation about this process, but the behavuiour of such key sequences in terminals is controlled by the terminal attributes (see termios(3)):

           ISIG   When any of the characters INTR, QUIT, SUSP, or DSUSP are received, generate the corresponding signal.

and

VINTR  (003,  ETX,  Ctrl-C,  or also 0177, DEL, rubout) Interrupt character (INTR).  Send a SIGINT signal.  Recognized when ISIG is set, and then not passed as input.

and

    VQUIT  (034, FS, Ctrl-\) Quit character (QUIT).  Send SIGQUIT signal.  Recognized when ISIG is set, and then not passed as input.

So it seems that the SIGINT signal in an interactive shell quits the current input pipeline, while SIGQUIT only kills the current child and continues the input pipeline.

So you can reach what you want by typing Ctrl-\ in the shell.

Actually tail does not care about signals and leaves the default set (I guess). So a SIGQUIT might cause a core dump (see signal(7)).

But you can also send a SIGINT to the tail process directly, which simply kills the child and leaves the input pipeline as is.

    echo "start shell: $$"; tail -f /tmp/watch-document ; echo "stop shell"

then in another terminal

    ps -efa | grep PID # (PID = the number after "start shell: " output)

    ingo@krabbe ~/src/laboratory/shell $ ps -efa|grep 7946 ingo 7946 3859 0 17:22 pts/6 00:00:00 -bash ingo 24238 7946 0 18:35 pts/6 00:00:00 tail -f /tmp/watch-document

There you see the PID of the tail and you can explicitly send a signal to the tail:

    kill -s 3 24328   # in my example case

To make all of this more comfortable it is usefull to read the pid of the tail in the command sequence:

    echo "start shell: $$"; tail -f /tmp/watch-document & pid="$!"; echo "$pid" 
>>/tmp/watch-document.pid; wait "$pid"; echo "stop shell"

By this way you will NOT quit the tail by CTRL+C, but you will call

    kill `cat /tmp/watch-document.pid`

To kill all started subprocesses to watch /tmp/watch-document that are started this way.

Actually the tail command needs to behave the way it is, because it is part of an essential set of POSIX tools that should behave exactly as defined.

If you want to send a "*q*" to the tail to control it, on what input line do you want to send it there? The tail process simply reads stdin, so that

    tail -f somefile

is the same as

    some-output-producer | tail -f

In the latter command line, you have tail -f to watch the stdout of some command, which is a very important use case. This tail -f could simply go down whe the "some-output-producer" sends EOF on the stdout channel (by closing it, for example).

What I want to say is: tail MUST stay agnostic to its input. If you have "*q*" somewhere in your "some-output-producer" line it should ot quit, but simply read it.
This way you can freely model such sequences:

    some-output-producer | tail -f | some-output-handler

Where "some-output-handler" could for example react on the "tail -f" output, by sending a signal to "some-output-handler", for example with awk:

    #!/usr/bin/awk -f
    /\*q\*/    { kill -s 2 "`cat /tmp/watch-document.pid`";
                 print "" >"/tmp/watch-document.pid"; exit 0; }
               { print }

This way you can define your command language that depends on your own process. That's the way how these coreutils POSIX commands should work: You can combine them and use them for your own process language. They stay agnostic to the input as far as possible.

Best regards

Ingo

On 21/10/18 11:13, Brian Wengel wrote:
Dear coreutils maintainer team



It seem you can only exit “tail –f…” sending *CTRL+C*, but that can be an
issue if you call it from another process that you want to keep running
after tail has exited.



Another example is “start daemon; tail -F logfile; stop daemon” as
user2394284 commented in this StackExchange
<https://askubuntu.com/questions/36785/tail-how-to-quit-tail-and-restore-terminal-window>
thread.



A good and gentle way to exit could be sending “*q*” just as e.g.
“journalctl –b” do.


I hope you'll consider my request.


And of course, a big thanks for the effort you put into the coreutils :-)


Best regards

Brian

Denmark




reply via email to

[Prev in Thread] Current Thread [Next in Thread]