[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