2 – Usando el signo de exclamación (!) para simplificar los comandos.

Posted on Oct 22, 2020 - by Franco

¿No les ha pasado que hacen un comando y les aparece el mensaje de permission denied entonces tienen que repetir el mismo comando, pero con sudo adelante? ¿O les ha pasado que crean un archivo y quieren en seguida editarlo? Hoy día vamos a ver algunos trucos para hacer el uso de Linux y Mac OS un poco más agradable.

Resumen de comandos

En este post veremos los siguientes atajos para hacer más eficiente nuestro uso de la línea de comandos.

!-n     # ref el 'n' comando anterior
!!		referencia el último comando completo (equivalente a !-1)
!:n 	ref. el argumento en la posición 'n' del ultimo comando
!$      ref. el último argumento del último comando (igual que usar '$_')
!:m-n   ref. los argumentos en el rango de 'm' a 'n'
!string referencia el último comando ejecutado que empieza con 'string'

Usando !-n

El atajo !-n nos sirve para referenciar un comando que hemos ejecutando previamente.

Por ejemplo, si hacemos los siguientes comandos:

sudo nginx -t 
sudo vim /etc/nginx/sites-available/mysite.com
sudo nginx -t

Vemos que estamos repitiendo varias veces el comando sudo nginx -t podemos evitar hacerlo con el atajo !-2 el número 2 indica que queremos ejecutar el comando ejecutado hace 2 comandos.

La serie anterior de comandos entonces se convertiría en:

sudo nginx -t 
sudo vim /etc/nginx/sites-available/mysite.com
!-2

Si bien es cierto, también podríamos usar la tecla arriba dos veces y alcanzar el mismo resultado. Sin embargo, la ventaja de conocer este atajo es que se puede usar también en scripts.

Usando !!  (repetir el último comando)

Por lo general queremos repetir el comando inmediatamente anterior, para eso tenemos un atajo (!!) . Veamos como usarlo. Por ejemplo, quiero crear un enlace simbólico (SymLink) en una carpeta en la cual el usuario no es el dueño por ejemplo:

ln -s /etc/nginx/sites-available/mysite.com /etc/nginx/sites-enabled/

A lo cual el comando arroja el siguiente error:

ln: failed to create symbolic link '/etc/nginx/sites-enabled/mysite.com': Permission denied

Lo más común es usar la tecla arriba para ver el último comando, y mover el cursor al principio de la línea y colocar la palabra sudo para correr el comando con los permisos necesarios:

sudo ln -s /etc/nginx/sites-available/mysite.com /etc/nginx/sites-enabled/

Sin embargo, hay una manera más sencilla: usar !! para repetir el comando anterior.

Entonces, el comando anterior completo se vería así:

>>> ln -s /etc/nginx/sites-available/mysite.com /etc/nginx/sites-enabled/
ln: failed to create symbolic link '/etc/nginx/sites-enabled/mysite.com': Permission denied
>>> sudo !!

De esta manera, !! es equivalente a todo el comando ln .../sites-enabled/ y nuestro comando realiza la acción que queremos hacer.

Usando!:n  (solo acceder uno de los argumentos)

Muchas veces no queremos copiar todo el comando anterior, solo uno de los argumentos. Por ejemplo, para crear un directorio y acceder a él luego de crearlo haríamos algo como:

mkdir -p /home/user/estructura/de/carpetas/
cd /home/user/estructura/de/carpetas

Esta vez usaremos el atajo ! seguido de : y  la posición del argumento que queremos recuperar. En este ejemplo, el argumento que queremos es el segundo /home/user/estructura/de/carpetas (el primero es -p) es decir podemos reemplazarlo por: !:2

mkdir -p /home/user/estructura/de/carpetas/
cd !:2

Y listo, hemos creado la carpeta y accedido a ella.

N.B.: Cabe destacar que no necesariamente puedes usar este atajo una sola vez en un comando puedes acceder a varios argumentos a la vez:

touch !:2 !:3 !:4 !:5

Usando !$ para obtener el último argumento

Un caso común es acceder el último argumento del comando ejecutado anteriormente. Si vemos la serie de comandos usada en el ejemplo anterior:

mkdir -p /home/user/estructura/de/carpetas/
cd /home/user/estructura/de/carpetas

Podemos reemplazar la ruta por !:2 para obtener este argumento como hemos visto anteriormente, pero podemos usar algo aún más simple !$ :

mkdir -p /home/user/estructura/de/carpetas/
cd !$

Y listo, hemos creado la carpeta y accedido a ella.

Si lo prefieren también pueden usar  $_, ambos tienen el mismo efecto.

Usando !^ para obtener el primer argumento

Algo quizás menos usado pero igual de útil podemos usar !^ para obtener el primer argumento del último comando.  Por ejemplo, el siguiente comando:

touch file1.txt file2.txt file3.txt
vim file1.txt

Puede simplificarse de la siguiente manera:

touch file1.txt file2.txt file3.txt
vim !^

Y listo, hemos creado el archivo y abierto para editarlo con vim.

Usando !:m-n para obtener un rango de argumentos

A veces queremos crear una serie de archivos y editarlos con vim de manera secuencial por ejemplo:

touch file1.txt file2.txt file3.txt
vim file1.txt file2.txt file3.txt

Esto lo podemos simplificar usando los argumentos posicionales que ya hemos visto por ejemplo:

touch file1.txt file2.txt file3.txt
vim !:1 !:2 !:3

Pero existe una manera más simple, usar la notación de rango, podemos obtener todos los argumentos de m hasta n. En este ejemplo nuestro comando podríamos simplificarlo a:

touch file1.txt file2.txt file3.txt
vim !:1-3

Podemos simplificarlo aun más, si el rango incluye el último argumento podemos usar $:

touch file1.txt file2.txt file3.txt
vim !:1-$

Usando !string

Por último, el atajo !string referencia el último comando ejecutado que empieza con ‘string’. Por ejemplo, tomemos la siguiente secuencia de comandos:

touch /etc/nginx/sites-available/mysite.com 
vim /etc/nginx/sites-available/mysite.com
nginx -t 
vim /etc/nginx/sites-available/mysite.com
nginx -t 

Vemos que repetimos exactamente el mismo comando de vim y nginx veamos como simplificarlo:

touch /etc/nginx/sites-available/mysite.com 
vim /etc/nginx/sites-available/mysite.com
nginx -t 
!vim
!nginx

De esta manera !vim se expande al último comando de vim y !nginx se expande al último comando de nginx. Cabe destacar que podrías usar sólo la primera letra del comando:

touch /etc/nginx/sites-available/mysite.com 
vim /etc/nginx/sites-available/mysite.com
nginx -t 
!v
!n

Esta serie de comandos es equivalente, pero quizá algo menos sencillo de entender, pero ya depende de cada uno como lo emplea.

Conclusión

Estos atajos que hemos aprendido hoy definitivamente nos van a servir en nuestro día a día. El que más utilizo es !! para repetir el comando anterior con sudo !! ya que a veces me olvido de incluirlo. Asimismo, !v para volver a ejecutar el comando anterior de vim es de mucha ayuda en mi día a día.

Fuentes y lecturas recomendadas