106

I often find myself in the following position: I've started typing a long command at the bash prompt, but half-way through I find out I need to check something with another command. This is a problem when I'm at the console (no X), which is often the case, because then I only have the following unsatisfactory ways to do it, that I know of:

  • Hit ctrl+alt+F2 and log in on another virtual console, and find out what I wanted, then go back and continue
  • ctrl+a, type echo + space + enter, find out what I wanted, press until I find my command, ctrl+a, del x 5, ctrl+e, and continue
  • Highlight what I've typed so far with my mouse (if gpm is running, which it usually is), press ctrl+c to interrupt, find out what I wanted while being careful not to use my mouse to highlight stuff, then press middle mouse button on a new prompt and continue
  • Pray to the command line gods that the half-written command will have no adverse effects but simply fail, and gingerly press enter, then find out what I wanted, press uparrow until I get my command back, and continue
  • Jump into my time machine, travel back in time and remind myself to start screen before starting to type command, travel back to the present, press ctrl+a c, find out what I wanted, press ctrl+a ctrl+a, and continue

So what I want to know is, is there some more elegant way of doing this? A sort of subshell-command or similar?

I'm most interested in methods that do not require any preparations or setup to work.

11 Answers 11

77

A somewhat faster version of alex's Ctrl+A Ctrl+K (which moves to the front of the line and then cuts everything forward) is to just use Ctrl+U, which cuts backward on bash, and the entire line (regardless of your current position) on zsh. Then you use Ctrl+Y to paste it again

4
  • 1
    Testing this, I conclude that Ctrl+U does not move back and cut forward, but rather cuts backwards. Having cursor in the middle of the command leaves whatever is behind it on the command line. Still a 33% improvement over @alex's solution though, since it saves a keystroke. Apr 7, 2011 at 21:18
  • 2
    @lazyr Oh, quite right; on zsh it does cut the entire line, but on bash it cuts backwards. I never noticed that difference before Apr 7, 2011 at 21:20
  • 2
    Oh, I didn't know Ctrl+U also puts text to kill buffer. Nice to know! :)
    – alex
    Apr 8, 2011 at 6:10
  • 1
    ^U ^K will have the same effect as ^A ^K but is marginally more ergonomic, and significantly more convenient under screen.
    – intuited
    Apr 19, 2011 at 5:04
55

Do ctrl-A to get to start of line, prepend a hash and press return - this way it will stay in the command history as a comment and you can get back to it with cursor up

EDIT: just noticed this is a slightly more elegant variant on your #2 ;)

7
  • 1
    Yes, and why didn't I think of that? Thank you! Apr 7, 2011 at 14:03
  • 1
    I need to read before I post my own answer. James has it right on.
    – Sean C.
    Apr 7, 2011 at 16:53
  • 4
    Note that this will not work in csh or zsh because they do not allow comments in the interactive shell. In zsh you need to activate the proper option: setopt interactive_comments. Apr 7, 2011 at 19:56
  • 1
    @Sam Yes, but ": command" has the same effect (":" = the null command)
    – user2267
    Apr 8, 2011 at 14:09
  • 6
    @barrycarter: no, : should be considered harmful for this purpose and never, ever be suggested. It will execute everything after a semicolon, inside backticks etc. with all the associated side effects. Apr 8, 2011 at 16:35
30

Hit Ctrl+A, Ctrl+K to move to the start of line and delete (kill) to the end of it. Then do your research, and when ready to continue hit Ctrl+Y (yank) to put your saved (killed) line back.

1
  • 3
    Ah, now this is more like what I had in mind. And I do that all the time in Emacs, should have thought about doing the same on the command line. Apr 7, 2011 at 18:50
14

In zsh, I type Ctrl+Z to “suspend” the command I'm typing and type another command. After I've run that command (or aborted it with Ctrl+C), the suspended command comes back for edition (even remembering the cursor position). As an additional convenience, if the command line is empty when I type Ctrl+Z, the key invokes the bg built-in instead (so a double Ctrl+Z sends a running command directly to the background).

fancy-ctrl-z () {
  emulate -LR zsh
  if [[ $#BUFFER -eq 0 ]]; then
    bg
    zle redisplay
  else
    zle push-input
  fi
}
zle -N fancy-ctrl-z
bindkey '^Z'          fancy-ctrl-z

I don't know how to do something similar in bash.

In any shell, you can use the low-tech method of adding a # at the beginning of the current line.

9
  • 2
    your function is admirable, but did you know that zsh has a function for that built in already? It's called push-line and all you need to do is use bindkey to get to it.
    – Caleb
    Apr 25, 2011 at 17:42
  • @Caleb: I don't know why I use push-input rather than push-line here, push-line does seem more appropriate (maybe old versions of zsh only had push-input?). But that's not a replacement for the rest of the function. Apr 25, 2011 at 18:17
  • As far as I can tell the only difference is the same-binding effect to background a running job. Am I missing something?
    – Caleb
    Apr 25, 2011 at 18:20
  • 1
    @Caleb: No, it's just that I find the combination of the two both convenient (push-line is useless on an empty line, having bg on Ctrl+Z is only useful when I've just suspended that process with Ctrl+Z) and mnemonic (I'm either backgrounding the process or the partial command line). Apr 25, 2011 at 20:39
  • 3
    @Caleb push-input suspends the whole input buffer, whereas push-line suspends only the current line. If I'm typing a multiline command, I want to suspend the whole command, so push-input is the right one. I find push-input more often useful than push-line (if I want to delay a line in a multiline input buffer, I can simply navigate to the beginning of the line and insert a newline), so I in fact wonder why push-line got the default keybinding and not push-input. May 2, 2013 at 9:50
14

In bash, just type Alt+#.

Then when you're ready, press Up then Alt+#.

The first puts a # at the start of the line to turn it into a comment, then accepts the line, as if you had pressed Enter.

Then, when you do it a second time, it sees the line already has a # at the start, so it removes it, and accepts it, again saving you the Enter key.

If the second time just inserts another #, then you have to type Alt+- Alt+# instead.

You can make zsh do the same by putting

bindkey -M emacs '\e#' pound-insert

in your ~/.zshrc.

Or, if you are using vi bindings, you can type # from command mode in both bash and zsh.

7
  • 2
    Doesn't work for me, the second command meant to remove the # just adds more #'s to the front. Apr 7, 2011 at 21:14
  • 1
    Does the first one work? What version of bash are you using?
    – Mikel
    Apr 7, 2011 at 21:19
  • 3
    Alt+# works as you describe in your third paragraph, but not as in your fourth, it simply prepends another # to the front and accepts the line. I use bash 4.1.5(1)-release on Ubuntu 10.10. Apr 7, 2011 at 21:24
  • 1
    Oh dear, in bash it requires a numeric argument, e.g. Esc+1 then Alt+# to toggle.
    – Mikel
    Apr 7, 2011 at 21:30
  • That works, but is a lot more cumbersome than just Ctrl+A Del Ctrl+E, especially on my keyboard layout where Alt+# is in fact Alt+Shift+3. Apr 7, 2011 at 21:39
11

One of my favorite features in zsh is the builtin push-line function that takes care of this without any of the hackery in other answers here. I have it bound to Ctrl+l in my .zshrc file like this:

bindkey '^L' push-line

Then when I'm typing along in some command and need to do something else real quick I can invoke that with one key and get a blank prompt. After running the other command, the prompt is automatically filled out with what I was typing before.

You can even chain multiple layers of this and the commands will come back at you in reverse order that you pushed them into the queue.

5
  • 6
    Bound to Ctrl+Q and ESC q by default (in emacs mode). Apr 25, 2011 at 20:37
  • Is there something similar for bash?
    – Magnus
    Oct 1, 2012 at 13:53
  • @Magnus: Please review the rest of the answers on this question. There are solutions for bash, just not as elegant as this.
    – Caleb
    Oct 1, 2012 at 13:58
  • @Caleb, I should have been more specific, is there a similar single key combination for bash?
    – Magnus
    Oct 1, 2012 at 14:11
  • 1
    This is clearly the “correct” answer, for Zsh anyway! I just want to mention the push-line-or-edit widget, which is not bound in any keymap by default. At the top-level prompt it does the same thing as push-line, but at any prompt level lower down it convert the entire command being entered to a multi-line buffer. Two great functions on one keybinding! I can recommend binding push-line-or-edit instead of plain push-line. You lose nothing, and gain useful functionality.
    – wjv
    Apr 5, 2016 at 7:38
5

In addition to the ctrl-a ctrl-k trick, if you're in screen, just ctrl-a d to detach then reattach with screen -r

You could also just open another window with ctrl+a c

2
  • 8
    If you're in screen, just open another window with Ctrl+A c. Apr 7, 2011 at 23:12
  • 1
    @Gilles .. unless you need to use some aspect of the shell state (variables, functions, aliases, etc.).
    – intuited
    Apr 19, 2011 at 5:05
4

An alternative way, not perfect though, press Ctrl-X Ctrl-E. This will open your default editor containing your half typed command. Then you may save your command to a file or open a new shell from within your editor. When you exit the new shell it will return you to the editor and saving the contents will automatically execute them.

This is not perfect because it doesn't return you to your original shell, but either forces the execution of the command or completely discards it. But there are no temporary selections or kill buffers to worry about, and there are also some nice tweaks, e.g. if editor=vi

:wq            # execute the command
:cq            # cancel and abort
:! command     # execute command
:shell         # open a new shell
:r filename    # insert the contents of a file for editing
:r ! command   # insert the output of a command for editing
2
  • Very nice alternative. I'm vi-emacs-agnostic, so I'll be happy as a clam using this when powertools are really needed. (Speaking of vi, I tried the N64 linux emulator Mupen64Plus a while ago. Esc quits the emulator without saving. I soon gave up playing anything.) Apr 7, 2011 at 20:04
  • 1
    @lazyr, for debian/ubuntu run sudo update-alternatives --config editor and choose your favorite editor. For other systems set the EDITOR or VISUAL environment variables to your favorite editor, e.g. add export EDITOR=/usr/bin/nano in your .bashrc.
    – forcefsck
    Apr 7, 2011 at 20:17
3

Using zsh, if you type <ESC> q (escape, then Q), your prompt line will be cut, so that you can type another command. You will automatically get back your cut text in the next prompt.

It can remember several lines at the same time, so you can use it while a line is waiting for you. You can even use it on blank line to delay the resume of your cut line.

It's not the most efficient way if you have to use several commands for the checking/preparation (you'll have to retype <ESC> q before each command). But I think that it is possible to bind it to a shorter shortcut.


If you just want to check the manual, type <ESC> h (escape, then H). That will run the run-help built-in, with the first word of the command line as argument. You'll find back your line intact once done.

1
  • Most terminals will let you do M-q instead of <ESC> q
    – sleblanc
    Sep 26, 2018 at 1:51
3

Similar to the method of adding # at the start of the line, there is an arguably simpler method that I use that doesn't require returning to the beginning of the line:

Just add an open quote and don't close it, whether single or double.

Then press Enter.

Then press CtrlC.

The partial command is saved in the command history (available via up arrow) but is not actually executed.

2

I've recently written a script for this. Just Ctrl+b to remember/restore command-lines.

Download:

Visit the repository.

Demo:

demo

You must log in to answer this question.

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