¿Cuáles son algunos trucos útiles de Bash que has visto o escrito? Estoy buscando trucos que no aparecen al leer el manual o los scripts aleatorios init.d.

Atajos en la línea actual

  • Ctrl + A: mover al inicio de la línea actual
  • Ctrl + E: mover al final de la línea
  • Alt + F: ir al final de la siguiente palabra
  • Alt + B: ir al inicio de la palabra actual o anterior
  • Ctrl + T: intercambia los dos últimos caracteres, por ejemplo: slls
  • Alt + T: intercambia las dos últimas palabras, por ejemplo: foo barbar foo
  • Ctrl + U: corta el texto del comando actual antes del cursor.
  • Ctrl + W: corta solo la palabra antes del cursor.
  • Ctrl + K: corta el texto del comando actual después del cursor.
  • Ctrl + Y: pega el texto cortado previamente después del cursor. Esto es útil cuando ha escrito un comando largo y se da cuenta de que se olvidó de hacer algo antes, por ejemplo:
      % ./my_long_command -v -u foobar -t -x 
     % ./do_something_before
     %   # pegar y ejecutar ./my_long_command… 
  • Alt + U: mayúscula la siguiente palabra, por ejemplo: lsLS
  • Alt + L: minúscula la siguiente palabra, por ejemplo: LSls
  • Alt + C: escribe con mayúscula la siguiente palabra, por ejemplo: fooFoo
  • Ctrl + L: borra la pantalla, dejando la línea actual en la parte superior.
  • Ctrl + _: deshacer (incremental).

Si no tiene una tecla Alt (Meta), puede usar escape: u es el mismo que .

Nota: estos accesos directos están disponibles con cualquier programa que use Readline, como la mayoría de los intérpretes de línea de comandos (python, irb, node, etc.).

Macros

Bash te permite grabar macros y reproducirlas después. AFAIK, solo puede ejecutar la última macro grabada. Escriba ( para iniciar la grabación, ) para finalizarla y e para volver a ejecutarla.

Interacción de la historia

Para interactuar completamente con el historial de Bash, debes entender tres cosas: los designadores de eventos, los designadores de palabras y los modificadores.

Los designadores de eventos se usan básicamente para seleccionar un comando que escribiste antes. Aquí están ellos:

  • !n refiérase al comando n . Por ejemplo !1 refiere al primer comando de su historial. No sé si algunas personas usan eso, ya que el historial de Bash suele ser grande (el mío contiene más de 4000 comandos).
  • Más interesante !-n refiérase al comando n líneas atrás. Significa que !-1 es el último comando. Hay un sinónimo para eso: !! . Así que, sudo !! le permite ejecutar de nuevo el último comando, precedido por sudo . También puede ejecutar de nuevo el comando antes del último con !-2 .
  • !str refiere al comando más reciente que comienza con str . Por lo tanto, si ejecutó recientemente make , puede ejecutarlo nuevamente con !ma (o incluso !m si no usó mv después).
  • !?str? refiérase al comando más reciente que contiene str (puede eliminar el final ? si la cadena es la última parte del comando). Digamos que recientemente ejecutaste tu increíble script de Python que muestra imágenes de gatos en toda tu pantalla. Pero está en un directorio muy profundo, así que tendrías que escribir de nuevo algo como ./foo/bar/python/awesome.py , y eres muy perezoso. Con este comando, puede escribir !?aw? y, suponiendo que no haya escrito un comando más reciente que contenga la cadena aw , ¡se ejecutará nuevamente su increíble script!
  • !# refiérase a la línea de comandos completa escrita hasta ahora. Entonces cd ..;!# Es equivalente a cd ..;cd ..; . Puedes usarlo muchas veces, así que cd ..;!#!# Es equivalente a cd .. cuatro veces.

Los designadores de palabras siguen a los designadores de eventos. Los dos deben estar separados por dos puntos (:), a menos que la palabra designador comience con ^ , $ , * , - , o % . Además, ” si se proporciona un designador de palabras sin una especificación de evento, el comando anterior se usa como evento ” (del Manual de referencia de Bash). Aquí están ellos:

  • $ refiere al último argumento. Entonces !!:$ refiere al último argumento ( $ ) del último comando ( !! ). Puede acortarse a !$ , Por ejemplo:
      ~% mv myfile.c foo / bar /
     ~% cd! $
     ~ / foo / bar% 

    También puede pasar el último argumento de todos los comandos anteriores con Alt +. (Gracias a Quora User).

  • n refieren a la n ª palabra. 0 es la primera palabra (el comando). Digamos que quiere editar el segundo archivo mencionado en el siguiente comando con vi: cat foo.h foo.c bar.c Utilice vi !!:2 .
  • ^ refiera al primer argumento (esto es equivalente a 1 , vea el designador de la palabra anterior). !!:^ (el primer argumento del comando anterior) puede ser reducido a !^ . P.ej:
     cat foo.c bar.c vim !^ # edit foo.c 
  • % refiere a la palabra que coincide con la más reciente ?str? buscar.
  • xy refiere a un rango de palabras. -y es equivalente a 0-y mientras x* es equivalente a x-$ , y x- es equivalente a x-$ sin la última palabra. Además, * es equivalente a 1-$ . Aquí hay dos ejemplos:
     cat foo.c foo.h vim -p !* # edit foo.c and foo.h 
     echo I love Quora !!:- Twitter # echo I love Twitter 

    Aquí, !! es el comando anterior, mientras que - es un equivalente de 0- que es equivalente a 0-$ sin la última palabra. Así que este atajo ejecuta nuevamente el comando anterior, eliminando su último argumento y reemplazándolo con ” Twitter ” (oye, eso es solo un ejemplo).

Ahora que puede acceder a los comandos anteriores y extraer algunas palabras de ellos, puede modificarlos para ejecutar versiones modificadas de estos comandos. ¡Los modificadores están aquí para eso! Tenga en cuenta que deben ir precedidos por dos puntos. Aquí están ellos:

  • h elimina un componente de ruta de acceso:
     cd /home/baptiste/Mail !!:h # cd /home/baptiste 

    Puedes usar dos veces (o más):

     ls foo/bar/xyz !!:h:h # ls foo 
  • t es lo opuesto a h , elimina todo excepto el componente de la ruta final:
     /bin/ls !!:r # ls 
  • r elimina un sufijo final:
     rm config.rc.save vim !^:r # edit config.rc 

    En este ejemplo !^ Es el primer argumento del comando anterior.

  • e es el opuesto de r , elimina todo excepto el sufijo final.
  • p imprime el nuevo comando pero no lo ejecuta:
     /bin/ls !!:r:p # display "ls" 
  • s/old/new/ sustituye new por la primera aparición de old :
     cd bat # oops, wrong directory !!:s/t/r/ # cd bar 

    Puede usar cualquier delimitador que desee (por ejemplo:: :s+old+new+ ), y omita el delimitador final si este es el último carácter de la línea. Además, si usa & en nuevo , será reemplazado por old (use \& si quiere evitarlo).
    ^old^new^ es un acceso directo para !!:s/old/new/ .

  • gs/old/new/ sustituye new por cada aparición de old . Funciona como s .
  • Gs sustituye a new por la primera aparición de old en cada palabra:
     echo bar car daar !!:Gs/a/u # echo bur cur duar 

Expansión de cuerdas y rangos

  • Expandir cadenas con llaves: xxx{A,B,C} se expande a xxxA xxxB xxxC . Esto es muy útil en algunos casos en los que necesita usar un nombre de archivo dos veces con pequeñas diferencias, por ejemplo:
     % mv {,.}foo # mv foo .foo % cp foo.rb{,.bak} # cp foo.rb foo.rb.bak % vim -p myfile.{c,h} # vim -p myfile.c myfile.h 
  • Bucle sobre un rango de números:
     # will print 17, 18, …, 42 for i in {17..42}; do echo $i; done 

    Esto también funciona con letras:

     # will print a, b, c, …, z for i in {a..z}; do echo $i; done 

    Puedes usar un paso diferente:

     # will print a, c, e, g, …, y for i in {a..z..2}; do echo $i; done 
     # will print 10, 20, …, 100 for i in {10..100..10}; do echo $i; done 

    También puedes probar la función seq que hace las mismas cosas, con un poco más de opciones.

Variables

Hay muchas variables predefinidas, aquí hay algunas útiles:

  • $OLDPWD contiene la ruta al último directorio en el que estaba, por ejemplo:
      [~ / one / path]% cd ~ / another / path
     [~ / another / path]% mv $ OLDPWD / myfile ./ # mueve un archivo
     # del último directorio de trabajo al actual 

    cd - es un atajo para cd $OLDPWD (gracias a Simon Josi).

  • $RANDOM le da un número entero aleatorio entre 0 y 32767. Si le asigna un valor, siembra el generador de números aleatorios.

Trucos misceláneos

  • Puedes incluir un archivo usando un punto ( . ), Esto es lo que uso en mi .bashrc :
     for f in ~/…/functions/*.sh; do if [ -x $f ]; then . $f; # include the file fi done 

    O más sucintamente:
    for f in ~/…/functions/*.sh; do [ -x $f ] && . $f; done

Ctrl + R para revertir la búsqueda a través de su historial de Bash. Ctrl + R sigue buscando, Ctrl + G cancela la búsqueda.

Además, agregaría estas líneas a tu .bashrc para que tengas más historial para buscar:

 export HISTSIZE=5000 export HISTFILESIZE=5000 alias h='history 100' 

Aunque el paquete Readline de GNU no es exclusivo de Bash (el shell interactivo de Python también tiene esto), la búsqueda inversa es uno de los aspectos más útiles de los shells de línea de comandos sobre las GUI.

Otro usuario mencionó pushd , pero no popd . Popd es lo contrario, significa “volver al directorio en el que estaba cuando ejecuté pushd”.

Pienso en ello como si estuvieras trabajando en un papel en tu escritorio, y alguien ponga algo por encima de lo que estás trabajando. Una vez que haya terminado con la interrupción, haga “pop”, devolviéndoles el papel y reanudando lo que estaba trabajando. Esto funciona con múltiples capas, también.

  [/ home / bkarwin] $ pushd / some / distant / directory
 [/ some / distant / directory] $ pushd / var / log
 [/ var / log] $ popd
 [/ some / distant / directory] $ popd
 [/ home / bkarwin] $ 

También hay cd – , que no empuja ni se abre, solo rebota entre dos directorios.

  [/ home / bkarwin] $ pushd / some / distant / directory
 [/ algún / directorio / distante] $ cd -
 [/ home / bkarwin] $ cd -
 [/ algún / directorio / distante] $ 

Entonces, finalmente, hay una manera de ejecutar un comando en un directorio remoto y volver automáticamente cuando se ejecuta el comando. Simplemente ejecuta el cd y el comando en una subshell:

  [/ home / bkarwin] $ (cd / some / distant / directory && pwd)
 / algunos / distante / directorio
 [/ home / bkarwin] $