20

I just learned that Linux has a sudo !! command which literally applies sudo to the last entered command. I had never heard about it.

Is that a common control? Where can I find documentation about it?

Mat
  • 52,586

3 Answers3

36

This is just bash shortcuts. It's not sudo!!, by the way. It's sudo !! (note the space).

The !! in bash is basically an expansion of the previous command.

Take a look at the "History Expansion" section of the bash man page:

http://www.gnu.org/software/bash/manual/bashref.html#Event-Designators

cjc
  • 2,837
29

It's actually sudo !!, which consists of the command sudo, with which you are probably familiar, and an event designator, !!, which refers to the last command entered. You can find more in the bash man page, under the Event Designators section.

Event Designators
   An event designator is a reference to a command line entry in the  his‐
   tory  list.   Unless  the reference is absolute, events are relative to
   the current position in the history list.

   !      Start a history substitution, except when followed by  a  blank,
          newline,  carriage return, = or ( (when the extglob shell option
          is enabled using the shopt builtin).
   !n     Refer to command line n.
   !-n    Refer to the current command minus n.
   !!     Refer to the previous command.  This is a synonym for `!-1'.
   !string
          Refer to the most recent command preceding the current  position
          in the history list starting with string.
   !?string[?]
          Refer to the most recent command preceding the current postition
          in the history list containing string.  The trailing  ?  may  be
          omitted if string is followed immediately by a newline.
   ^string1^string2^
          Quick  substitution.   Repeat  the  previous  command, replacing
          string1 with string2.  Equivalent  to  ``!!:s/string1/string2/''
          (see Modifiers below).
   !#     The entire command line typed so far.
Mat
  • 52,586
Kevin
  • 40,767
3

This separation of functionality is one of the most beautiful design principles making Linux/Unix so much more powerful than other alternatives where each program is a separate independent island of conventions and capabilities.

"make each program do one thing, and do it well"

Rather than implementing !! inside sudo (or any other command) which can benefit from repeating the previous command -- it is implemented once (in the shells) and all commands can benefit from it. So you can do:

$ echo !!     # will echo the last command
$ time !!     # will repeat and time the last command
$ strace !!   # will repeat the last program while system-call tracing it

and so on.

But it doesn't end here. The shell does much more than expanding history via the ! event designators. Before executing your command, it does variable expansion, file-name wildcard expansion (globbing), command substitution, file/IO redirection, and much more. All of which can be leveraged and used in any command that's being invoked from the shell.

Another big advantage is that if you spend some time learning your shell ('man bash' in this case) you need to learn it once and you can use these powerful capabilities everywhere, all the time. It is much easier to learn one set of powerful principles and conventions, rather than relearn how command line agrs are handled in each program or utility.

arielf
  • 41