Repeat last command with "sudo"

I often forget to run commands with sudo. I'm looking for a way to make a bash function (or alias) for repeating the last command with sudo. Something like:

S() {
sudo $(history 1)
}

Any ideas?

34081 次浏览

!! can be used to reference the last command. So:

sudo !!

Not enough?

sudo !!

if you want the S simply put:

alias S=sudo

and use it

S !!

the !! mean the last command

Use alias redo='sudo $(history -p !!)'. This is the only thing that I have found that works with aliases. The other answers do not work in aliases for some reason, having tried them myself, even though they do work when directly running them.

Adding and expanding upon aaron franke's response (which is correct but lacking a why) such that simply typing redo works after configuring the alias alias redo='sudo $(history -p !!);

This is the only thing I found that works with aliases

There are a few things going on that warrant explanation.

alias redo='sudo !!'

doesn't work as it doesn't execute the sudo portion, though it does resolve the !!.

To get the sudo !! to resolve correctly, a shell resolution directive has to execute and concatenate along with sudo. So we do;

alias redo='sudo $(history -p !!)'

By specifying the right side of the alias to $(history -p !!), what this does is say to the shell;

  1. redo is an alias, assess the right side of the =
  2. sudo remains as is and it concatenated to...
  3. $() is a shell directive, to execute the contents within the current execution process (as oppose to a sub-shell ${}, which spawns a different process to execute within)
  4. Resolve history -p !!
  5. The !! gets expanded to history -p <lastCommandHere> as a result of step 4.
  6. The -p part says to history to only print the results, not execute
  7. The sudo, executes the remaining (now printed out on the same command line), with elevated privileges, assuming password was entered correctly

This ultimately means that the command history -p !! effectively writes out the resolution rather than executing after the sudo.

NOTE: The ' is significant. If you use ", the !! gets interpolated twice and to achieve our purpose we need to very carefully control the resolution steps; single/double quotes in bash

PS

If you're using zsh + oh-my-zsh, there is a sudo alias setup for _ such that you can do;

_ !!

Which will rerun the last command as sudo. However, if you're configuring the alias in ~/.zshrc, the alias redo='sudo $(history -p !!) will not work as is from the zsh config as the resolution steps are different.

That said, you can put the alias into ~/.bashrc instead of ~/.zshrc and have the same result when executing the alias redo from zsh (assuming you're sub-shelling zsh from bash, though this is admittedly a bit of a kludge - though a functional one).