Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I edit current shell command without executing it?

Tags:

bash

There seems to be quite a lot of information on how to edit and execute a command using your editor using "edit-and-execute-command (C-x C-e)", but what I would like to achieve is take the current shell command, apply certain filtering (using a script) and then return it to prompt for further approval/manual changes before execution. Is this possible with bash?

like image 943
Piotr Mazurek Avatar asked Jan 16 '20 14:01

Piotr Mazurek


People also ask

How do you edit shell?

At a bare shell prompt, you're effectively in vi text-input mode: the characters you type appear on the command line. If you want to edit, press ESC to go to command mode. Then you can use typical commands like dw to delete a word and ct. to change all characters to the next dot on the line.

How can you edit command line in bash?

Command line editing is enabled by default when using an interactive shell, unless the --noediting option is supplied at shell invocation. Line editing is also used when using the -e option to the read builtin command (see Bash Builtins). By default, the line editing commands are similar to those of Emacs.

Which command replace current shell with command that is being executed?

Whenever we run any command in a Bash shell, a subshell is created by default, and a new child process is spawned (forked) to execute the command. When using exec, however, the command following exec replaces the current shell. This means no subshell is created and the current process is replaced with this new command.


1 Answers

Latest update based on my experience

The part 0"+y$dd in the following mapping is really something that you should carefully think about and tailor it to your taste/workflow/experience.

For instance, very frequently I've found myself ending up with multiple lines in the buffer, where I only want to execute the one the cursor is on; in this case I can use 0"+y$dd:%d<CR> instead of 0"+y$dd.

And this is just one of the possible scenarios.

Final answer for those who like vim

  • Set vim as your EDITOR/VISUAL, so that when editing a command line, you will use vim to edit it.
  • Put au BufEnter /tmp/bash-fc.* nn <Leader>d 0"+y$dd:wq<CR> in your ~/.vimrc file to map Leaderd (which you will rarely use when editing a command) to the action "delete the current line into the + register without the trailing EOL".
    • you can use either the + or the * register in the mapping above; the ways to paste into the terminal will likely differ; you need the +clipboard option for these registers to be available.
  • When finished editing a command in the vim editor, hit EscapeLeaderd.
  • Paste the clipboard into the terminal (this is terminal-dependent).

Original answer

I often need to do the same, and I do it as follows. (I normally use the set -o vi in bash, so points 1 and 2 in the following are different if you use set -o emacs, the default; based on your question it looks like points 1 and 2 are unified in Ctrl+x followed by Ctrl+e, which is harder to type, imho.)

  1. hit Escape to be in normal mode,
  2. hit v to enter the editor to edit the command,
  3. edit the command as I like,

(This is where you ask the question.)

  1. hit Escape0"+y$dd:wq,
    • Note: 0"+y$, not simply "+yy, as the latter would copy the newline too, and this would result in executing the command upon pasting it in the command line,
  2. paste the clipboard on the command line
    • how to do this depends on the terminal you are using, I guess; I hit Ctrl+Alt+v in URxvt.
  3. proceed to approval/manual edit.

Clearly this is just a workaround, consisting in copying the edited command into the clipboard before deleting the whole command, so that nothing gets executed upon exiting the editor; however it's the best I can get for myself.

Update

As my EDITOR (and VISUAL) is equal to vim, when I edit the command, I edit it in vim.

In this respect, I have noticed that the buffer is named /tmp/bash-fc.random, where random is a 6-characters alphanumeric random string.

This gives space to a lot of possiblities, if you use vim as your editor, as you can define some mapping in your .vimrc to execute the whole sequence Escape0"+y$dd:wq. For instance, one command that you'd rarely use when editing a command line is Leaderd; therefore you can put the following mapping in your .vimrc file

au BufEnter /tmp/bash-fc.* nn <Leader>d 0"+y$dd:wq<CR>

so that step 4 in the above recipe becomes

  1. hit EscapeLeaderd
like image 127
Enlico Avatar answered Sep 20 '22 04:09

Enlico