3

Suppose I try removing a directory with

rm ./somedir

This will throw up the error saying

rm: random-scripts/: is a directory

is there a shortcut to re-execute previous command any option? (-r in this case)

Wondering if there is an alternative to hitting up arrow and editing old command.

Something like these:

  • !! replays last command.
  • sudo !! replays last command with sudo.
  • !! some-arg replays last command with some-arg as argument.

3 Answers 3

2

You can say:

!rm -r

this will expand your previous command and add the -r flag into it. That is, it will say

rm ./somedir -r

Another example:

$ echo 23
23
$ !echo 44    # expands to "echo 23 44"
23 44
Sign up to request clarification or add additional context in comments.

3 Comments

But the -r flag needs to be inserted before the arguments. if inserted after arguments, the command searches for a directory or file named '-r' to delete.
@jeffpc1993 no. Test it: mkdir ttt; rm ttt -r
Warning to use this kind of stuff when the history is not your own... on a unix server with ksh when running as a user that others also have access to this might give highly unexpected results - but appreciate the idea and possibilities on a normal linux single user box
0

If you're using a modern shell like bash, you should be able to use the up-arrow to get the last command back (keep pressing for previous commands), then use the left and right arrows to move around inside the command text. Anything you type will be inserted at the cursor location - you can use the BackSpace and Del keys to remove any of the characters.

3 Comments

I know this. I was looking for a shortcut. like !! replays last command. and sudo !! replays last command with sudo.
So you want to type something like !! -r? I don't believe that would be very applicable to many commands - you have to put the options in certain places, in the correct order... Sorry.
yes. I also know !! won't work here. Just wondering if there is a shortcut to add options to previous command. Looking for ways to increase speed working on terminal
0

It's simple using interactive history expansion (needs set -H, which is the default in interactive sessions).

Important note: while you're experimenting with history expansions (and even if you're not experimenting), I suggest you turn on the histverify shell option with

shopt -s histverify

With this option turned on,

history substitutions are not immediately passed to the shell parser. Instead, the expanded line is reloaded into the Readline editing buffer for further modification.

(Quote from the Bash Reference Manual). In fact, I even suggest you put shopt -s histverify in your .bashrc.


If you typed

rm dir1 dir2

you got an error; in fact you meant rm -r dir1 dir2, here's how you can fix the command:

  1. You want to replace the string rm with rm -r:

    !!:s/rm/& -r/
    

    Explanation.

    • !! refers to the last command (it's much safer to use !! than to use !, since !! forces the substitution to be performed on the previous command, and not on a matching previous command; just in case). The column (:) is the character that separates the event designator (here !!) from the word designator (that is unused—empty—here) and the modifier.
    • The modifier used here is s/rm/& -r/ which means: replace (the first) occurrence of rm and replace it with itself (&) followed by -r.

    When you type this (and with histverify turned on), you should have the following line in your readline buffer:

    rm -r dir1 dir2
    

    ready to fire, with the cursor at the end of the line. The same can be achieved by repeating the command rm and not using &:

    !!:s/rm/rm -r/
    
  2. Same as above in shorter form: a shortcut for

    !!:s/old/new/
    

    is

    ^old^new^
    

    hence, you could have typed this instead:

    ^rm^& -r^
    

    It's more cryptic and will certainly impress your little sister.

  3. You want to keep all the arguments (here dir1 and dir2) and replace the command (i.e., the 0-th word) with a new one (here, replace the command rm with rm -r):

    rm -r !!:1-$
    

    Explanation. The !! refers to the last command and the column is the separator, as before. But now, we're selecting the range of words 1-$, i.e., the first to the last (indexing starts at 0, so that the command rm is the 0-th word). Very handy to run a new command with the old arguments.

  4. Same as above using a shortcut:

    rm -r !!:*
    

    That's right, * is a shortcut for the range 1-$.


There's much more to what I gave here; I hope it's a good start for you to understand and experiment with the material provided in the reference manual.


In your specific case, namely

rm ./somedir

I wouldn't even bother with history expansions at all: shells have the special variable _ that expands to the last argument of the previous command. So typing

rm -r "$_"

would fix that! but this only works with the last argument of the last command… for more arguments, you'll need to use the interactive history facility.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.