127

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.

  • 14
    Using commands like more, less, tail, head may be an interesting alternative to cat. (of course this is not an answer...) – tonioc Jan 1 '15 at 11:37
  • 25
    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. – Lenz Jan 5 '15 at 2:45
  • 4
    Does double-take at sidebar question from another SE site Is very relieved to see "UL" logo next to question. Nevermind, carry on. (usually, it's Arquade that has the looks-very-wrong-out-of-context question titles) – LindaJeanne Jan 5 '15 at 13:41
  • 11
    I would try the curiosity command... – Sekhemty Jun 29 '15 at 18:20
  • 3
    alias curiosity='sudo killall cat' – cas Jul 8 '16 at 15:15
76

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.

  • 6
    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). – RJHunter Jan 1 '15 at 16:08
  • 11
    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 ... – Martin Tournoij Jan 1 '15 at 17:52
  • 1
    @Carpetsmoker Tested that, didn't stop the flow of text for me on Ubuntu 14.04 + terminator + zsh. – muru Jan 1 '15 at 19:13
  • @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). – Martin Tournoij Jan 1 '15 at 20:08
  • 4
    @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 Jan 1 '15 at 21:15
4

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
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.

1

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.

  • Ctrl-O doesn't seem to be implemented in modern Linuxes, at least not RHEL or Ubuntu server. – dotancohen Feb 24 '15 at 21:37
-1

When using bash, you can suspend the job using Ctrl+Z and then kill it, either using the PID or by following the answers from https://stackoverflow.com/questions/1624691/linux-kill-background-task (e.g. kill -9 %%)

  • 3
    but I am using tcsh and Ctrl+Z is not working... already stated that in question. – JigarGandhi Jan 1 '15 at 13:55
  • yeah, sorry, didn't read in your post that you tried Ctrl+Z and I wrongly assumed that Ctrl+Z is handled by the shell in contrast to Ctrl+C which is handled by the application. That's why I thought Ctrl+Z worked instantly while Ctrl+C doesn't. – Jannis Jan 7 '15 at 14:45
-1

open a new console, for example by clicking onto the console icon or by pressing Ctrl+Alt+F2. There, enter

killall -9 cat

and cat will be killed unless you have a stale NFS lock or an "uninterruptible sleep" situation (read on a bad sector with no timeout set).

  • 10
    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). – Stéphane Chazelas Jan 1 '15 at 19:54
  • Then please try echo 3 > /proc/sys/vm/drop_caches which will drop a lot of buffers as well. – Thorsten Staerk Jan 1 '15 at 20:46
  • 7
    No, that would only drop cached data never things like that as that would affect functionality! – Stéphane Chazelas Jan 1 '15 at 20:54
  • 4
    @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). – peterph Jan 1 '15 at 21:52
  • 1
    Wouldn't the killall -9 cat also kill any other cat instances that might still be doing good things in other process threads? – Joe Jan 8 '15 at 1:38
-7

You can try with this

Reset the display use ctrl-j

If cat is still running then open a new terminal and run this pkill -9 -f cat " This will kill all cat processes. "

  • Ctrl + J doesn't work – JigarGandhi Jan 1 '15 at 10:46
  • 26
    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... – tonioc Jan 1 '15 at 11:23
  • 2
    For example, pkill -f cat on my desktop would kill the system tray area of Xfce4's taskbar. – Mark Jan 2 '15 at 8:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.