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?
This is just bash shortcuts. It's not
sudo!!, by the way. It's
sudo !! (note the space).
!! in bash is basically an expansion of the previous command.
Take a look at the "History Expansion" section of the bash man page:
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.
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.