¿Qué significa `!!` en `sudo !!`?

64

Soy un usuario de Ubuntu con poca experiencia y he estado usando sudo.

¿Qué hace sudo !!y cómo?

RamHS
fuente
77
Duplicado de, excepto desde el otro lado: Ejecutar el mismo comando nuevamente pero como sudo
un CVn
66
@WarrenHill no quiere el "cómo" sino el "qué" y el "cómo". Pide más sobre la !!parte del comando.
Braiam
1
@Nakilon no debería estarlo. Esta pregunta es qué !!hacer y cómo. El otro quiere un método para hacer esto.
Braiam
@ MichaelKjörling te referías a lo relacionado ¿verdad?
Braiam
2
@Braiam En realidad, quise decir duplicado; las dos respuestas más votadas a esa explican específicamente qué sudo !!hace, y hay dos respuestas que realmente explican específicamente qué !!hace.
un CVn

Respuestas:

74

!!en bash es un alias para el comando anterior (ver Designadores de eventos ). Por lo tanto, vuelve a ejecutar el comando anterior con sudopermisos.

cronitis
fuente
15
Nota: los !comandos generalmente no están disponibles en scripts de bash (solo en sesiones interactivas). Se pueden deshabilitar con set +o histexpand.
Benoit
64

sudo bang bang es un comando muy útil cuando se trabaja en la interfaz de línea de comandos.

Algunas distribuciones de Linux le permiten iniciar sesión como usuario en lugar de administrador.

Por lo tanto, para hacer algo de forma administrativa, debe continuar el comando con sudo(Super-User DO), que le dice al sistema "usted hará esto, porque yo lo dije". / bang-bang (! = bang) es básicamente un atajo que puedes usar para repetir el comando anterior.

Entonces, el escenario típico es que intentas un comando y devuelve un mensaje diciendo que tienes que ser un administrador para hacerlo. Por lo tanto, puede escribir sudopara ejecutar ese comando como superusuario / administrador, o puede escribir sudo !!donde !!le dice al sistema que use el comando anterior que se intentó. UfH

Hay muchos otros comandos bang. Para obtener una lista de ellos y explicaciones de lo que son, consulte Linux Bang Commands , consulte también Historial de Bash y comandos de explosión

Mitch
fuente
12
También es un comando muy peligroso si no estás 100% seguro de cuál era tu comando anterior. Casi siempre es más seguro presionar la flecha hacia arriba, luego la tecla de inicio, luego escribir sudoy mirar la línea de comando.
Shadur
3
@Shadur Por lo general, su comando anterior fue hace aproximadamente 1 segundo. El caso de uso normal es el que se describe en la respuesta: te olvidas de sudoalgo y obtienes un error, por lo que inmediatamente quieres sudohacerlo
Michael Mrozek
1
@Braiam: CLI es una abreviatura. ¡Violación de la regla comunitaria! ¡Ataque! ¡Reeditar!
Indio
44
sudono significa "super-usuario hacer", no hace falta que haga un comando como si lo hubiera hecho su(es decir, su interruptor de usuario [y no super usuario]); es decir, puede sudo comandos como cualquier usuario, no solo root ( -uswitch); mismo ocurre consu [user] [-c command]
ssice
1
@Mitch, excepto suque no significa tal cosa. Ver linux.die.net/man/1/su , gnu.org/software/coreutils/manual/html_node/su-invocation.html , linfo.org/su.html . Debe significar usuario sustituto .
ssice
38

El bang bang (!!)comando es un atajo para repetir y ejecutar el comando anterior que ingresó en su terminal. Este comando es muy útil cuando olvida que necesita derechos de administrador para realizar una determinada acción y le permite repetirlo con derechos de superusuario simplemente escribiendo,

sudo !!

!! agarra el último comando de ejecución.

Por ejemplo:

apt-get update

La salida será,

E: No se pudo abrir el archivo de bloqueo / var / lib / apt / lists / lock - open (13: Permiso denegado)
E: No se pudo bloquear el directorio / var / lib / apt / lists /
E: No se pudo abrir el archivo de bloqueo / var / lib / dpkg / lock - open (13: Permiso denegado)
E: No se puede bloquear el directorio de administración (/ var / lib / dpkg /), ¿eres root?

Después de eso, si ejecutamos el sudo !!comando, la salida será

Hit http://extras.ubuntu.com saucy/main amd64 Packages
Get:3 http://mirror.sov.uk.goscomb.net saucy-updates Release.gpg [933 B]
Hit http://ppa.launchpad.net saucy Release                                  
Hit http://extras.ubuntu.com saucy/main i386 Packages 
Hit http://mirror.sov.uk.goscomb.net saucy Release                             
99% [Waiting for headers] [Waiting for headers] [Waiting for headers]

Lo que significa que la !!parte toma el comando de ejecución anterior apt-get updatey la sudoparte anterior hace que el comando se ejecute con derechos de superusuario.

Y cómo los sudo !!ejecuta el comando anterior con privilegios de superusuario, normalmente significa todos los comandos que entramos en el terminal se almacenan en la command history.Llevar el historycomando en el terminal, que muestra todos los comandos que entered.The !!parte en las sudo !!agarra el último comando almacena en el historial de comandos y el conjunto sudo !!ejecuta el último comando con privilegios de administrador.

Algunos otros comandos de explosión se explican en esta publicación de blog .

Avinash Raj
fuente
3
Me sorprende ver que menciona 'bang bang' nuevamente. Pensé que una vez era suficiente.
kiri
1
+1 para más ejemplos de comandos de explosión.
WernerCD
1
@Rmano Al menos en Bash, y espero que todos los shells de estilo Bourne con soporte de historial, mkdir LongDirectoryNamey cd !$se emitan por separado para funcionar, a menos LongDirectoryNameque haya sido la última palabra del comando anterior. Para fines de historial de shell, mkdir LongDirectoryName; cd !$es un comando. Interaccione el historial con !!, !^y !$use el último comando que el shell realmente procesó completamente antes de ver !. Aquí hay un ejemplo. Si ejecuta history, verá que los comandos en una línea unida ;se recuerdan como un solo comando.
Eliah Kagan
@EliahKagan tienes razón! Información incorrecta eliminada ...
Rmano
13

La respuesta tiene dos partes: !!ysudo

!!es parte de la funcionalidad del shell (en el caso de Ubuntu esto probablemente sea bash, pero otros shells como zsh o csh también lo admiten) llamado "expansión de historial". Se comporta de manera similar a otras expansiones en que el shell expande el 'marcador de posición' a un conjunto de palabras. Si bien foo*se expandiría a una lista de todos los archivos que comienzan con 'foo', !!se expande al contenido de la línea de comando anterior.

$ echo foobar
foobar
$ echo !!
echo foobar
$ !!
echo foobar

Al igual que otras expansiones, esto se hace completamente por el shell, por lo que si escribe !!después de algún otro comando, este comando no es consciente de que hubo un !!, pero solo verá la línea de comando anterior. (A diferencia de otras expansiones, la expansión del historial ocurre antes de que un comando se guarde en el historial, es decir, en lugar de !!la línea de comando reemplazada se guardará en el historial).


El sudocomando permite ejecutar comandos como otro usuario, siempre que los permisos sean otorgados por la política de seguridad (el valor predeterminado está configurado en /etc/sudoers).

Por defecto, la contraseña de root permanece sin configurar en Ubuntu. Para realizar tareas de administración del sistema, el usuario creado durante la instalación tiene derechos de sudo. Este usuario ahora puede ejecutar cualquier comando en el shell como root, simplemente anteponiendo sudo. Algunos programas GUI también usan el mecanismo sudo, por ejemplo, la gestión de paquetes.

La razón por la que sudopuede ejecutar otros comandos como root (u otro usuario) es que el sudo binary ( /usr/bin/sudo) tiene el bit setuid establecido en su permiso y pertenece a root. Cualquier ejecutable (binario) con bit setuid establecido se ejecuta con los permisos de su propietario. Esto significa que sudo se ejecuta efectivamente con permisos de root sin importar qué usuario realmente lo haya llamado. Solo las políticas de seguridad internas de sudo administran a qué usuario se le permite qué y evitan que los usuarios arbitrarios hagan cosas arbitrarias.


Entonces, en el caso de sudo !!esto significa

$ mount /dev/sdb1 /mnt
mount: only root can do that
$ sudo !!

es básicamente idéntico a

$ mount /dev/sdb1 /mnt
mount: only root can do that
$ sudo mount /dev/sdb1 /mnt

solo menos escribiendo. En ambos casos, sudo solo lo ve mount /dev/sdb1 /mnty lo ejecuta con permisos de root.

Adaephon
fuente
5

!!es la expresión sintácticamente más simple y probablemente más común para la expansión de la historia .

Como habrás notado, después de sustituir el último comando ejecutado !!, bash hace dos cosas (en su configuración predeterminada):

  1. Se muestra el comando completo con el texto sustituido.

    Por ejemplo, si su comando fue lshw -c videoy usted ejecuta sudo !!luego, entonces el comando después de la expansión del historial es sudo lshw -c video.

  2. Ese comando se ejecuta.

Normalmente, estos dos pasos ocurren sin interrupción y sin oportunidad para la interacción del usuario, ya que no shopt histverifyestá configurado de forma predeterminada ( shopt -u histverify).

Sin embargo, si habilita shopt histverify( shopt -s histverify), la expansión del historial funciona de manera diferente:

  1. Obtiene una nueva solicitud principal, con el texto expandido ingresado automáticamente. Es como si hubiera escrito ese texto usted mismo, con el cursor al final, pero aún no ha ejecutado el comando.
  2. Usted, el usuario, debe presionar Enterpara ejecutar el comando. O puede editar el comando, cancelarlo ( Ctrl+ C), etc. Tenga en cuenta que este no es un aviso especial, sino un aviso primario regular. Realmente es como si hubiera escrito el texto usted mismo.

(Tenga en cuenta que la histverify opción de shell solo tiene efecto si se está utilizando la biblioteca readline , pero cuando usa bash de forma interactiva en un Ubuntu u otro sistema GNU / Linux, este es esencialmente el caso).

Independientemente de si la histverifyopción de shell está habilitada o no , la expansión del historial es diferente a muchas otras expansiones de shell. Otras expansiones de shell no le muestran el comando expandido antes de que se ejecute. A diferencia de otras expansiones, que están destinadas a usarse de manera interactiva y no interactiva (por ejemplo, en un script de shell), la expansión del historial casi siempre se usa de manera interactiva.

Eliah Kagan
fuente
3

! se usa en Linux para atajos relacionados con la historia. Entonces, !! simplemente ejecutará el comando anterior que ejecutó.

Es muy útil en los casos en que olvidas poner sudo antes de un comando que lo requiere o obtienes permiso denegado o algo así simplemente

sudo !!
y tu estas listo.

tapananand
fuente
0

!! repetirá y ejecutará el comando anterior, y con sudo le dará al comando el privilegio de root. (¡¿No está en la página de manual? !! No puedo verlo allí.)

Farimah
fuente
Para cualquiera que busque la página de manual:man --pager='less -p "Event Designators"' bash
Sebi