37

When I do tail -f filename, how to quit the mode without use Ctrl+c to kill the process?

What I want is a normal way to quit, like q in top.

I am just curious about the question, because I feel that killing the process is not a good way to quit something.

14
  • 25
    tail is not interactive; it does not take commands.
    – muru
    Aug 22, 2017 at 7:13
  • 5
    There is also difference between killing process with SIGTERM (default) and SIGKILL. SIGTERM 'asks' process to stop, and this signal can be handled by program. On the other hand SIGKILL actually kills the process. See man signal for more
    – mrc02_kr
    Aug 22, 2017 at 7:56
  • 11
    The premise of this question is faulty. That special character does not "kill" the process in the way that you are thinking. It sends the interrupt signal to it, not the kill or terminate signals.
    – JdeBP
    Aug 22, 2017 at 8:02
  • 7
    It's perfectly reasonably to interrupt tail or even kill it without worry. But if you want an alternative, consider most, which has an admittedly under-documented "follow" mode, initiated with Shift+F, and can be cleanly exited with Q. Aug 22, 2017 at 15:49
  • 6
    The problem here is your perception that "killing the process is not a good way to quit something" -- sending ^C to a process is one way of saying "I'm done with you and I'd like you to stop", it is the "default" way to exit from a terminal process in Linux. If you're choosing to exit from some long running process, the repercussions of your choice to stop it may leave a mess, but tail -f isn't that :)
    – Josh
    Aug 22, 2017 at 21:34

8 Answers 8

55

As said in the comments, Ctrl-C does not kill the tail process, which is done by sending either a SIGTERM or SIGKILL signal (the infamous -9...); it merely sends a SIGINT which tells tail to end the forward mode and exit.

FYI, these's a better tool:

less +F filename

In less, you can press Ctrl-C to end forward mode and scroll through the file, then press F to go back to forward mode again.

Note that less +F is advocated by many as a better alternative to tail -f. For difference and caveats between the two tools, read this answer: Is `tail -f` more efficient than `less +F`?

10
  • 7
    Off-topic. The OP did not ask to "end the forward mode and scroll through the file". Rather, the OP asked how to quit tail -f without using Ctrl+C
    – fpmurphy
    Aug 22, 2017 at 10:08
  • 8
    @fpmurphy1 Given that the OP's question premise is incorrect (tail is not killed by CTRL-C and is not interactive) I believe my answer is more than appropriate.
    – dr_
    Aug 22, 2017 at 11:37
  • 14
    @fpmurphy1 If you take the OP literally yes it's off-topic, however I prefer educational answers that address misunderstandings and at the same time give an answer to what the OP was actually trying to achieve, i.e. the real question.
    – MarioDS
    Aug 22, 2017 at 11:58
  • 15
    "Ctrl-C does not kill the tail process" - Yes it does. Or at least as much as kill <pid> does. For most programs, there's no real difference between Ctrl-C (=SIGINT), SIGTERM and, to some extent, SIGKILL. The default action for all three is to simply terminate the process, as if exit() had been called, with the exception that for SIGKILL, none of the user-mode code associated with exit() is called (so no atexit() cleanups etc). Ctrl-C and SIGTERM, in particular, are completely identical unless the program explicitly catches either and acts on it. GNU tail doesn't.
    – marcelm
    Aug 22, 2017 at 12:02
  • 4
    @marcelm Terminating the process is not the same as exit() being called. exit() will run the atexit() handlers, and clean up open stdio files (most importantly flushing output buffers). A SIGINT handler could do this, but most programs don't bother; I don't know whether tail does.
    – Barmar
    Aug 23, 2017 at 17:46
19

What I want is a normal way to quit, like q in top.

That's ControlC :)

I am just curious about the question, because I feel that killing the process is not a good way to quit something.

^C (ControlC) sends a SIGINT to the process, which is defined as:

The SIGINT signal is sent to a process by its controlling terminal when a user wishes to interrupt the process

That's exactly what you want to do here, is interrupt tail. There's no other way to accomplish what you're trying to do ("nicely" quit tail) and while other answers provide a means to stop tail in other ways, they're no better.

Pressing ^C will attempt to interrupt a task in Linux -- this is perfectly normal, and it's only "not good" if that process is in the middle of something and you're not letting it finish, and then the only "not good" side effect is leftover things from that process. As an example, ^C in the middle of a make command leaves partially-compiled software, but that's fine: a further run of make will clean that up / resume where it left off.

3
  • 2
    Actually, the make example is a reminder why we always write .DELETE_ON_ERROR: in our Makefiles - we want Make to remove partially-written intermediate files when it learns that one of its commands received a signal. Aug 23, 2017 at 7:26
  • Processes can trap SIGINT and do cleanup before exit as indicated in Toby's .DELETE_ON_ERROR: example. Aug 23, 2017 at 15:45
  • 1
    Yes, the ability to trap SIGINT is exactly why I said it's what @Arthur wants. There's no need to be "nice" to tail, you won't hurt it's feelings with a ^C :)
    – Josh
    Aug 23, 2017 at 19:44
12

tail -f filename, how to quit the mode without use Ctrl c to kill the process

You can't do that. Perhaps you wanted to run tail -f somefile | less

The Ctrl c is interpreted by the tty subsystem (and by your shell) and sends a SIGINT signal (see signal(7) and pty(7)...). See tty demystified.

0
7

This would work and answers your question, but is not a particularly satisfactory solution.

timeout 15s tail -f /var/log/messages

This will run the command for 15 seconds and then kill it for you, without having to press ^C

3
  • 5
    Yeah, so would shutting down the computer tail is being run on. Still, you're not wrong I guess.
    – Aaron
    Aug 22, 2017 at 13:00
  • 5
    How is terminating tail with SIGTERM better than terminating it with SIGINT? Aug 22, 2017 at 14:53
  • 1
    @DmitryGrigoryev You're totally right - its not better. But this answer directly answers the OP's question, even though its not really a lot of use in reality. However I have used timeout to terminate things like ping, when using a Dell DRAC Java app that requires a menu selection to press Control and a second menu choice to release control (that was just irritating, a Dell c5220 blade )
    – Criggie
    Aug 22, 2017 at 20:08
0

Assuming you have a function

function prll(){
..... 
pkill -9 -x tail
}

Assuming you run tail along your function

tail -n 1 -f file | 
pv -l > /dev/null | 
prll file

echo !!done!!

Conclusion, the answer is:

pkill -9 -x tail
-1

Answers differ based on context. To quit tail -f elegantly, you will need a trigger. Assume you are trying to monitor output of a task that will finish at some point in time - that can become your trigger.

task >& filename.log &
task_pid=$!
tail -f filename.log &
tail_pid=$!
while [ 1 ]
do
    # -0 is a special "poke" signal - "are you around?"
    kill -0 $task_pid
    if [ $? -eq 0 ]
    then
        # Original task is still alive.
        sleep 2
        continue
    fi
    kill -TERM $tail_pid
    break
done

I have used similar ideas in the past.

Enjoy.

-1

I think another good approach is using the old ps + kill in another session.

ps -fea | grep tail

The above command would identify any tail running by any user, and after finding the right PID, just run kill. For example:

kill 999999

Hope this can help someone as an alternative approach.

1
  • That does exactly what the OP wanted to avoid (»I feel that killing the process is not a good way«). Your answer is not only more complicated, it makes things worse by sending SIGTERM, while the simple ctrl-c would send a smooth SIGINT.
    – Philippos
    Jun 9, 2022 at 7:08
-2

Issuing

echo tail -n 1 -f <filename>

works for me though I'm not 100% sure it terminates the tail process.

1
  • 2
    The command you show does not do anything other than output the strings tail, -n, 1, -f and the filename with spaces between them.
    – Kusalananda
    Jun 2, 2022 at 16:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .