8

I need to open a file named -. (I am playing this hacker game)
And when I try to use command cat -- - , after I type that, any command I type does not work, for that fact, everything I type just repeats itself after I hit enter.

I assume I entered into some type of loop or extended command mode or something.

What do I type, or press to get out of this "loop" ?

commands keep repeating

Just to be clear, I typed "hhel" once, and it showed up twice, I typed "test" once, and as you can see in the photo, it showed up twice in the terminal.

Kusalananda
  • 333,661
kakashi7593
  • 97
  • 1
  • 3
  • 1
    nit: a terminal doesn't anything, it's just an input/output device. The shell is what attaches to a terminal, run commands and prints outputs to that terminal – phuclv Dec 08 '22 at 05:28
  • @phuclv, here, apart from the first prompt and the command entered, it's cat that reads from and writes to the terminal, not the shell – ilkkachu Dec 08 '22 at 21:22
  • 1
    @ilkkachu but Terminal won't execute any command is absolutely wrong. The terminal can't run commands. Only the shell parses and runs commands – phuclv Dec 09 '22 at 04:33
  • @phuclv, I didn't say anything about the terminal. – ilkkachu Dec 09 '22 at 09:10
  • 1
    cat is incapable of opening a file named by an argument -, because it is hard-coded to treat an argument of - as a synonym for standard input. Using -- doesn't do anything, because - isn't treated as an option in the first place. cat -- - is exactly the same as cat -. – chepner Dec 09 '22 at 19:58

2 Answers2

36

Running cat -- - is effectively the same as running just cat. The - is understood to mean standard input, but cat's default behaviour without any arguments is to read standard input anyway. As for the duplicating text, that's the terminal echoing your input as you type it (the first time) and cat reading input and printing it to output (which is also to the terminal, hence showing the text a second time).

To exit this, press CtrlD on a new line. You can also use CtrlC to send SIGINT to cat, causing it to die.

To view the contents of a file called - in the current directory using cat, use

cat ./-
Kusalananda
  • 333,661
muru
  • 72,889
12

What do I type, or press to get out of this "loop" ?

muru's answer already mentions that you can press Ctrl-D or Ctrl-C to get out of this situation, but it's worth remembering that these key combinations can get you out of almost all unwanted situations at a terminal, not just this one, as well as why they do what they do.

  • Ctrl-D sends EOF (end of file) to the current program. If the program is designed to read from your terminal "until EOF" and then exit (a lot of programs are), then Ctrl-D will get you out of it. cat is one such program.
  • Ctrl-C sends an Interrupt signal to the current program. This will exit the program, unless the program is specifically designed to do something else on interrupt (or it depends on some third party program/library that does). So this is generally more powerful than Ctrl-D. There are very few terminal programs, other than those that use TUIs (text-based user interfaces), that won't immediately exit when you press Ctrl-C.
  • There's also Ctrl-Z, which backgrounds the current program. This doesn't exit the program, but it does (generally) give you your terminal back. Just like Ctrl-C, programs can override this, but usually don't unless they're using a TUI. After using Ctrl-Z, you can get back into the program where it left off by entering fg. Or you can use ps -a to find the PID of your errant process, and then kill -9 <PID>, to get rid of it completely.
  • Finally, if none of those work, but you're using a GUI, you can open a second terminal and use ps and kill there, as above.

As a bonus, sometimes you'll end up with a terminal that's "partly" working but not displaying correctly, or seems to be stuck doing nothing at all when you're sure you got rid of that errant program. In this situation, you can try entering reset (blindly - and don't forget to hit enter at the end) to get your terminal back (it doesn't lose any data, but it does do things like making sure your input gets displayed if some program has turned that off and not turned it back on again).

Keiji
  • 391
  • 4
    no need to look for the PID of a backgrounded process, just kill %1 – ilkkachu Dec 09 '22 at 09:29
  • 3
    Also worth knowing about Ctrl+, that'll send SIGQUIT. It's still blockable, but less likely to be blocked than SIGINT. – James_pic Dec 09 '22 at 09:57
  • 1
    Ctrl-D is interpreted by the terminal itself to "close" standard input. Nothing is actually sent to the foreground process; it is simply notified when it tries to read past the end of its standard input. – chepner Dec 09 '22 at 20:00
  • 1
    @chepner, technically, ^D just tells the terminal to send to the reading process whatever it currently has in the input / line editing buffer, instead of waiting for a newline. If you've entered a partial line, ^D will pass it to the reader, and if you've entered nothing, it'll result in a zero-byte read for the reader, many of which will then interpret it as an EOF and exit. But the reader doesn't have to do that, it can ignore it and/or do something else, and then continue reading from the terminal. Try e.g. setting IGNOREEOF=5 in Bash, and then hit ^D a couple of times. – ilkkachu Dec 10 '22 at 13:14
  • Hm, I wonder where I got my idea of how ^D behaves? I know I was thinking of stty eof ^D as a terminal-level setting, but the man page for stty doesn't provide any information about what, exactly, "eof" means. – chepner Dec 10 '22 at 15:43
  • @James_pic Wow, for some reason I always thought SIGQUIT was supposed to be sent with Ctrl+Q, and wondered why it never worked for me. Just tested Ctrl+\ and it works. Thanks for correcting this misunderstanding of mine! – Keiji Dec 12 '22 at 06:59