¿Hay alguna forma de ejecutar comandos desde el historial?

99

Por ejemplo:

[root@ip-10-0-7-125 ~]# history | grep free
  594  free -m
  634  free -m | xargs | awk '{print "free/total memory" $17 " / " $ 8}'
  635  free -m
  636  free -m | xargs | awk '{print "free/total memory" $9 " / " $ 10}'
  736  df -h | xargs |  awk '{print "free/total disk: " $11 " / " $9}'
  740  df -h | xargs |  awk '{print "free/total disk: " $11 " / " $8}'
  741  free -m | xargs | awk '{print "free/total memory: " $17 " / " $8 " MB"}'

Me pregunto si hay alguna forma de ejecutar el comando 636 sin volver a escribirlo, simplemente escriba algo más el número, como el historial 636 o algo así.

El único
fuente
14
sabe usted de ctrl-r?
Carlos Campderrós
1
Sí, lo sé, pero no es exactamente lo que quiero.
The One

Respuestas:

171

En bash, solo !636estará bien.

usuario164825
fuente
12
In Linux- Esto tiene más que ver con el shell (bash, zsh, etc.) que una persona está ejecutando y luego con el sistema operativo en el que lo está ejecutando. Hay shells en linux sin soporte para la historia.
Zoredache
@Zoredache Y de manera similar, esto funciona bien en la mayoría de las implementaciones de bash en Windows.
Ajedi32
1
No solo bash, por supuesto, sino también otros shells, incluido csh.
Dibujó el
55
Si tiene un comando que es muy similar al que desea ejecutar, puede agregar :pimprimir el comando sin ejecutarlo, !636:ppor ejemplo. Lo que significa que puede volver a seleccionarlo fácilmente desde su historial presionando la flecha hacia arriba y realizar los cambios menores que desee
AJefferiss
78

Sí, se llama "expansión de la historia". Ver

LESS='+/^HISTORY EXPANSION' man bash

para más detalles

El uso de un signo de exclamación seguido de un número es posiblemente el uso más simple:

!636

Sin embargo, también puede ejecutar el último comando ejecutado directamente sin conocer su número de historial:

!!

O puede ejecutar dos comandos de regreso:

!-2

Sin embargo, la forma que uso con más frecuencia es repetir el último argumento del último comando:

echo this text goes into a file > /tmp/afile.txt
cat !$

O, digamos que estoy inspeccionando un archivo. Usando la finalización de pestañas, podría hacer lo siguiente:

ls -l /really/long/path/to/some/file
less !$

Nuevamente, lea la página del manual para más detalles:

LESS='+/^HISTORY EXPANSION' man bash
Comodín
fuente
25
Interactivamente, Alt-.puede ser más conveniente que !$. Inserta el último argumento del último comando textualmente en la línea.
ulidtko
2
@ulidtko ¿Dónde están documentados esos escapes especiales (lo sabía !$, pero nunca supe Alt-.)? ¿Publicarás un enlace, por favor?
edmz
55
LESS="+/DEFAULT KEY BINDINGS" man 3 readline, /etc/inputrc, ~/.inputrc. Muchos programas además de bash usan libreadline; para aquellos que lo hacen, obtiene las mismas funciones como Alt-., Ctrl-X-U(deshacer), Ctrl-/(describir acceso directo), completar pestañas, etc., de forma gratuita. Por ejemplo, con solo tres líneas de PYTHONSTARTUPuna puede habilitar la finalización de pestañas y el historial en el stock python REPL . Que funcionará (principalmente) igual que en bash, ya que es la biblioteca GNU Readline la que hace el trabajo. La página de manual de readline describe las características en detalle.
ulidtko
2
Además, Ctl-UpArrow (o AltUpArrow en bash) se desplazará hacia atrás a través de la lista del historial. Al escribir algunos caracteres, la flecha arriba solo obtiene los comandos que comienzan con esa letra, por ejemplo, "fr (Ctl-Up)" se desplaza a través de todos los comandos "gratis ..." en la lista del OP. Esto también funciona en cosas como gnuplot y gdb que usan readline.
jamesqf
2
@ Ajedi32, vea la línea final en negrita en mi respuesta. :) A decir verdad, esta respuesta es apenas una muestra de lo que puede hacer la expansión de la historia . Tenga en cuenta que esto está en el nivel del shell, no en el comando que está llamando; por lo tanto, echo {1..5}seguida por touch !$tocará cinco archivos, no sólo uno. Hablando estrictamente, no es el último argumento, sino la última palabra de shell en esa línea. (Intente también echo hello >tempseguido de echo goodbye !$). Si puede pensar en una forma de expresarlo con mayor claridad, no dude en sugerir una edición.
Comodín el
14

Una buena pregunta, si no quieres primero el historial, anota el número, etc.

en bash (y tal vez otros):

ctrl-r something 

( ctrl-r= "búsqueda inversa interactivamente") ( something= una parte de un comando anterior)

Esto le mostrará la última línea del historial que contiene something. Para obtener el anterior, haga ctrl-r (solo) nuevamente, cada vez que obtenga una línea anterior.

ex:

ctrl-r  10

para mostrar la última línea del historial que contiene '10' (por ejemplo, la línea con $10, en su ejemplo), y ctrl-rnuevamente hasta que recupere la línea del historial que estaba buscando

Cuando aparece la línea que deseaba, solo Enterpara ejecutarla (o también puede editarla, usando el arrow keys, backspacey ctrl-apara ir al principio de la línea, ctrl-epara llegar al Fin, ctrl-kpara "matar" desde el cursor hasta el final de la línea (= elimina + lo guarda en un búfer),: ctrl-ypara restaurar, desde el búfer, un bit muerto previamente, etc.)

Si desea buscar hacia adelante (ctrl-s), primero debe deshabilitar XON : consulte https://stackoverflow.com/a/791800/1841533 :

"solo para deshabilitar XON / XOFF ejecutando

stty -ixon

"(y luego podrá usar ctrl-s, sin tener que congelar el terminal)

Olivier Dulac
fuente
Si hago esto y accidentalmente presiono ctrl-r demasiadas veces, ¿hay alguna forma de buscar nuevamente en el historial?
Kasperd
@kasperd: Sí puedes. muchas respuestas en sí lo señalan: ctrl-s para búsqueda hacia adelante.
Olivier Dulac
Desafortunadamente, ctrl-s se usa para congelar el terminal, y bash no deshabilita eso, por lo que no funciona en la configuración predeterminada. (Otros programas, como emacs, desactivan la combinación de teclas para congelar el terminal de modo que se puedan usar ctrl-s para la búsqueda.)
kasperd
@kasperd: Sí, lo siento por no mencionar eso antes (señalé "muchas respuestas" porque precisan eso, pero no me tomé el tiempo para escribir esto en el comentario o dar un enlace ... (Estaba usando mi teléfono). Ahora regresé a casa y podría editar eso en la respuesta anterior. ctrl-s para la búsqueda del historial de bash necesita que stty -ixon primero
Olivier Dulac
Ese comando va a romper el uso normal de ctrl-s, por lo que esa no es realmente una opción.
Kasperd
7

Puede usar el shell incorporado fc :

fc -s 636
Steven Penny
fuente
2
En realidad, esto es mejor que la respuesta aceptada, pero debe eliminarla -spara obtener los beneficios. Si ejecuta fc 636, abrirá un editor con el comando 636 de su historial en el búfer, y cuando guarde y salga del comando (modificado o no) se ejecutará. Y aún mejor, este es compatible con POSIX .
Comodín
@StevenPenny Gracias. Y sí, sé lo que es POSIX, aunque no veo la relevancia. Independientemente, alguna documentación de fácil acceso e incluida sería buena.
Faheem Mitha
@FaheemMitha intente ejecutar "help fc".
Comodín el
@Wildcard helpno es POSIX - podría tener que hacer man dasho similar
Steven Penny
@Wildcard Gracias. Tiendo a olvidar que helpexiste. Otro caparazón incorporado. Y desconcertante para los usuarios incautos que podrían querer ayuda con un nuevo sistema, pero en cambio se enfrentan a una corriente de galimatías. :-(
Faheem Mitha
3

Hay HSTR- hhcomando para bashy zshselección de comando interactivo, mejor que la búsqueda inversa Ctrl-R:

hh ejemplo de comando de historial interactivo

es interactivo, por lo que puede buscar y editar el comando antes de ejecutarlo.

En Ubuntu, puede instalar hhcon el siguiente one-liner:

sudo add-apt-repository ppa:ultradvorka/ppa && sudo apt-get update && sudo apt-get install hh && hh --show-configuration >> ~/.bashrc

o paso a paso:

sudo add-apt-repository ppa:ultradvorka/ppa
sudo apt-get update
sudo apt-get install hh

Instalar hhen Fedora, RHEL o CentOS:

sudo dnf|yum install hstr -y

En macOS con homebrew:

brew install hh

... luego configúrelo con:

hh --show-configuration >> ~/.bashrc

Esto reemplazará el comportamiento predeterminado de Ctrl-R.

Ejecute hh --show-configurationpara determinar qué se agregará a su perfil de Bash.

Más opciones de configuración disponibles en la página de inicio del proyecto en Github: https://github.com/dvorka/hstr

modlin
fuente