How to kill a runaway cat?

30,939

Solution 1

If the file(s) in question contain really lots of data sending the signal can actually get to cat before it finishes. What you really observe is the finite speed of your terminal - cat sends the data to the terminal and it takes some time for the terminal to display all of it.

Remember, that usually it has to somehow redraw the whole output window for each line of output (i.e. move the contents of the window one line up and print the next line at the bottom). While there are techniques and algorithms to make this faster than if it was done the straightforward way, it still takes some time.

Thus, if you want to get rid of the output as quickly as possible, hide the terminal window, because then usually no actual redrawing takes place. In graphical environment this can mean either minimising the window or switching to a different virtual desktop, on the Linux virtual console just switch to another one ((Ctrl +)Alt + Fx).

Also notice that if you ran this over a slow network link (SSH over a GSM connection for example), you would definitely see much less output before cat got killed by the signal, because the speed of the terminal wouldn't be the bottleneck any more.

Solution 2

Terminal Setup

I reckon this is more to do with the way the terminal is set up, than with any buffering issue. Check the output of stty -a | grep intr, you should have intr = ^C; on the output line if Ctrl-C is enabled at the tty/pty. If it isn't, you can use stty intr ^C to enable it. Add the line to your .tcshrc or .login to make it permanent (or delete the line that changes it in the first place!).

Failing Ctrl-C, you can also try sending SIGQUIT with Ctrl-\. If this doesn't work, again check stty -a | grep quit to see if it is properly set up.

Terminal Emulator Setup

Also check the settings for your terminal emulator (if you are using one), it may be that there is a shortcut set up at this level (maybe for copy or something) and the Ctrl-C does not reach the pty level. A shortcut could also be set up somewhere else in your desktop environment or Window system.

A good test on Linux if you are using a terminal emulator is to switch to a Linux console (Ctrl-Alt-F1), login there and see if the same behaviour occurs. If it doesn't then this suggests the problem lies with your Window system or terminal emulator.

It could be an issue with the delay between data being read from the pty device as suggested by peterph. But if this is the case and you do actually have to wait minutes for the data to be displayed, then surely the terminal emulator is buffering way too much data (or your PC is very slow). The answer would be to find a way to reduce that buffer size in your terminal emulator settings or use a different one.

Extra Tip

Something else worth adding; I usually end up in the runaway cat situation when if I accidentally cat a binary file. The other effect of this can be to screw up your terminal settings (if the binary data happens to match various terminal escape codes which it often does). If tput is installed (usually is by default), you can avoid having to restart with the following command:

tput reset

Solution 3

This is what tmux option c0-change-interval and c0-change-trigger designed for. You should use a screen manager for resumable session anyway.

Solution 4

The Ctrl-O option has been in Unix since the 110 baud days. Runaway cat commands were always a problem when a long ASCII file was dumped at the slow output device and the the entire file placed in the device driver output buffer. Ctrl-O would start the flush of the buffer and a follow up Ctrl-O would toggle off the flush so the cat could be read at normal speed. Ctrl-O was entered and the entire file would flush and quickly return a command prompt.

Whether or not Linux device driver coders felt the need to continue to add this feature is unknown. This feature was added at the device driver level where Ctrl-S and Ctrl-Q could only be implemented. I used this to dump large debugging runs with lots of check print and then scroll down to the place I needed to see.

Share:
30,939

Related videos on Youtube

JigarGandhi
Author by

JigarGandhi

VLSI Engg. currently working as VLSI RnD Engg. Enjoy TCL scripting & shell scripting. loves rubik cubing & cycling too

Updated on September 18, 2022

Comments

  • JigarGandhi
    JigarGandhi over 1 year

    Many times I accidentally run the cat command on files that have contents up to few thousand lines.

    I try to kill the cat command with Ctrl+ C or Ctrl+Z, but both only take effect after the total output of cat is displayed in the terminal, so I have to wait till cat gets completely executed.

    Is there a better solution that avoids waiting? Because sometimes the files are up to size of 100MBs, and it gets irritating to wait for it.

    I am using tcsh.

    • tonioc
      tonioc over 9 years
      Using commands like more, less, tail, head may be an interesting alternative to cat. (of course this is not an answer...)
    • JigarGandhi
      JigarGandhi over 9 years
      that's correct @tonioc but its like torture when I use cat for very big files.. have to wait for few minutes.
    • muru
      muru over 9 years
      @Braiam I'm adding back the tcsh tag because OP's having problems with tcsh.
    • Jeff Hammond
      Jeff Hammond over 9 years
      OP asked "Is there a better solution that avoids waiting?", to which I answer: Try using the "more" command instead of "cat". The "cat" command should never be used on large files for exactly the reason that you are seeing. I recognize that this does not answer the other question, "How to kill a runaway cat?"
    • Kent Pawar
      Kent Pawar over 9 years
      What I usually do is first check the number of lines using wc -l in the file and then use less to go through it page-wise.
    • Admin
      Admin over 9 years
      That was the greatest question title I've ever read. Until I saw that the question's link was for UL, I thought you needed help killing an absconding feline.
    • Eduard Florinescu
      Eduard Florinescu over 9 years
      I love the double-entendre of the title!
    • ChuckCottrill
      ChuckCottrill over 9 years
      Try ^S to stop output to your terminal, then ^C to kill it.
    • Sekhemty
      Sekhemty almost 9 years
      I would try the curiosity command...
    • Alessio
      Alessio almost 8 years
      alias curiosity='sudo killall cat'
    • IW16
      IW16 over 7 years
      @cas You missed the -9
    • G-Man Says 'Reinstate Monica'
      G-Man Says 'Reinstate Monica' over 6 years
    • Vorac
      Vorac almost 4 years
      @Lenz you have probably not been around too long. "How to kill the parents, leaving the children alive?" (unix.se); "How to get away with murder?" (rpg.se). Unfortunately I can't find them now.
  • JigarGandhi
    JigarGandhi over 9 years
    Ctrl + J doesn't work
  • tonioc
    tonioc over 9 years
    pkill with '-f cat' is quite dangerous, since the -f will look for 'cat' pattern in whole command lines, which is likely to occur, and cause unwanted results...
  • JigarGandhi
    JigarGandhi over 9 years
    but I am using tcsh and Ctrl+Z is not working... already stated that in question.
  • RJHunter
    RJHunter over 9 years
    If you're waiting on the data to come down a slow SSH pipe, you can use the OpenSSH escape sequence to close the connection. On a new line, type ~? to see the available options (~. closes).
  • Martin Tournoij
    Martin Tournoij over 9 years
    You also try stopping output with Ctrl+S which sends tty-stop-output. You can then send Ctrl+C. To resume output, press Ctrl+Q ...
  • muru
    muru over 9 years
    @Carpetsmoker Tested that, didn't stop the flow of text for me on Ubuntu 14.04 + terminator + zsh.
  • Stéphane Chazelas
    Stéphane Chazelas over 9 years
    The problem is not with cat, it's about what cat has written to the terminal before dying and has not been read let alone processed or displayed by the terminal emulator yet (and is sitting in a (around 64kiB large on Linux) buffer inside the pty driver).
  • Martin Tournoij
    Martin Tournoij over 9 years
    @muru Thanks. I tried to test it, but wasn't able to reproduce the problem (my system is too fast, it would seem, or maybe I didn't try hard enough).
  • Thorsten Staerk
    Thorsten Staerk over 9 years
    Then please try echo 3 > /proc/sys/vm/drop_caches which will drop a lot of buffers as well.
  • Stéphane Chazelas
    Stéphane Chazelas over 9 years
    No, that would only drop cached data never things like that as that would affect functionality!
  • peterph
    peterph over 9 years
    @Carpetsmoker I'm afraid software flow control (which is Ctrl+S) won't help that much in this case (of a fast terminal link) - the data is already in the terminal buffer and waiting for the terminal to process it. Hence Ctrl+S will tell the application to stop sending more data, but what has already been sent will still have to be displayed.
  • peterph
    peterph over 9 years
    @RJHunter sure, but you often don't want to kill the connection. Which is one of the many reasons terminal multiplexers are so useful especially over network connections.
  • peterph
    peterph over 9 years
    @ThorstenStaerk drop_caches controls pages used as cache by the kernel (usually for a file system), not internal buffers of terminals, network drivers and such - if it did, it would have quite grave consequences as Stéphane pointed out (basically you would lose data).
  • Mark
    Mark over 9 years
    For example, pkill -f cat on my desktop would kill the system tray area of Xfce4's taskbar.
  • smali
    smali over 9 years
    just close the terminal and open a new one.
  • gokhan acar
    gokhan acar over 9 years
    Wouldn't the killall -9 cat also kill any other cat instances that might still be doing good things in other process threads?
  • dotancohen
    dotancohen about 9 years
    Ctrl-O doesn't seem to be implemented in modern Linuxes, at least not RHEL or Ubuntu server.