9

I often forget to run a command with sudo, so I find myself often typing sudo !! immediately afterwards.

I tried aliasing this, but bash chokes on the !! part. Is there some way to represent this shortcut within an alias?

andrewdotnich
  • 285
  • 1
  • 10
  • That's not a wild-card that's a history expansion feature. History expansion is performed before alias expansion so when the alias is expanded the `!!` are considered literal. – Dennis Williamson Feb 01 '11 at 01:54

2 Answers2

11

AIUI the problem is that history substitutions (!!) are done before alias substitution. I haven't tested this thoroughly, but it looks like fc can be used to get what you want:

alias sudothat='eval "sudo $(fc -ln -1)"'
Gordon Davisson
  • 34,084
  • 5
  • 66
  • 70
  • 1
    No need for the `eval` (plus it may have some undesirable effects). – Dennis Williamson Feb 01 '11 at 01:38
  • Without the `eval`, it won't parse things like the quoted strings correctly, and with double-quotes around the results of `fc` it should evaluate everything exactly once -- which is what you want. – Gordon Davisson Feb 01 '11 at 03:47
  • @Dennis Williamson: I've now tested this a bit more thoroughly, and it seems to work as expected (i.e. the same as typing `sudo !!`) for everything I've tried -- quoted arguments, pipelines, command substitutions, command substitutions containing command substitutions containing pipes... I don't see any way to do this right without an eval. – Gordon Davisson Feb 19 '11 at 15:45
7

From a colleague at work:

alias sa='sudo `history -p \!\!`'

appears to do the trick

andrewdotnich
  • 285
  • 1
  • 10
  • 1
    it should be noted that this only works when using single quotes ('). – Torian Feb 01 '11 at 03:42
  • This won't handle quoted arguments properly -- for example, if you use it to rerun `echo "a   b"` (which prints `a   b`), it'll print `"a b"` (as in, the quotes are actually included in the arguments passed to `echo`, but the spaces between aren't). – Gordon Davisson Feb 01 '11 at 03:50