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?
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.
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.
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.
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.
vim
vim
as your EDITOR
/VISUAL
, so that when editing a command line, you will use vim
to edit it.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".
+
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.vim
editor, hit EscapeLeaderd.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.)
(This is where you ask the question.)
URxvt
.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.
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 map
ping 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With