64

I'm trying to set an alias for sudo !! in Bash. I tried alias sbb='sudo !!', but it interprets that as a literal !! and prints

sudo: !!: command not found

If I use double quotes, it substitutes the double bang in the string itself, so that doesn't work.

Is there any way to make this work? Or an alternative alias? `

Bernhard
  • 12,272
Manishearth
  • 1,007
  • 2
  • 10
  • 12

6 Answers6

74

!! is expanded by bash when you type it. It's not expanded by alias substitution.

You can use the history built-in to do the expansion:

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

If the command is more than a simple command (e.g. it contains redirections or pipes), you need to invoke a shell under sudo:

alias sbb='sudo "$BASH" -c "$(history -p !!)"'
rici
  • 9,770
  • Got one for tcsh? – mdpc Aug 02 '13 at 19:02
  • 1
    @mdpc: I don't use tcsh, but I glanced at man tcsh and discovered that it does do history expansion during alias expansion "as though the original command were the previous input line." Interesting. However, alias sbb 'sudo \!-2 did not work as expected (it actually substituted the second previous entry); alias sbb 'sudo \!\!' did work as expected (substituted sbb for !!); and in the end it turned out that what I wanted was alias sbb 'sudo \!-1' which I would have expected to be the same as \!\!. (tcsh 6.17.06 (Astron) 2011-04-15) YMMV. Good luck. – rici Aug 02 '13 at 21:10
  • Thanks! This alias is great when as administrator you forget to put sudo in front of your command. – mdpc Aug 02 '13 at 21:42
  • instead of sbb I would prefer prease as alias as suggested by @jpschorr – rubo77 Jul 07 '16 at 05:52
  • usage: sudo -h | -K | -k | -V – alper Jan 22 '22 at 20:57
53

Try:

alias sbb='sudo $(fc -ln -1)'

I like actually prefer to name it 'please':

alias please='sudo $(fc -ln -1)'

Info: fc is a in-built command in the bash shell. that lists, edits and reexecutes commands previously entered to an interactive shell.

Zsh has the similar issue with !! and aliases, and fc -ln -1 also works there. Though caveats about getting redirections and other shell syntax inside the sudo'ed command line apply, so you may want to wrap the command within a shell invocation or eval, see @rici's answer.

ilkkachu
  • 138,973
jpschorr
  • 631
6

Now there's a repository for this purpose in GitHub, it magically checks whether it needs superuser rights, also fixes the typos:

https://github.com/nvbn/thefuck

Arda
  • 161
1

Worth noting that for zsh if you share history between multiple shell instances (SHARE_HISTORY option), you really want to restrict fc lookup to the instance you're currently using. Otherwise, you'll get all of the commands issued since your shell's last one, joined together on a single line.

alias please='sudo $(fc -Lln -1)'
yacoob
  • 121
  • 2
-1

This was originally posted at this question but later, suggested to post here.

Here is how you can use fc and history with alias for !- like substitutions. Suppose if you want to use !-n (where n is digit for nth last command used), then you can use fc and history with alias as follows:

  1. Using history:

    alias xyz='echo $(history -p "!-<n>") ; sudo $(history -p "!-n")'
    

    Note: Here !-n should be enclosed with ' or ''.

  2. Using fc:

    alias xyz='echo $(fc -ln -n -n) ; sudo $(fc -ln -n -n)'
    

    Note: here 1st and 2nd -n are used to specify the range of history list.

Here I used echo-ing before executing command for felling like !-<n>.

Pandya
  • 24,618
-3
alias please="sudo $(history -p \!\-2)"
chaos
  • 48,171