¿Existe un acceso directo para ejecutar una serie de comandos en bash history?

20

Supongamos que tengo el siguiente ejemplo trivial en mi history:

...
76 cd ~
77 ./generator.sh out.file
78 cp out.file ~/out/
79 ./out/cleaner.sh .
80 ls -alnh /out
...

Si quisiera ejecutar comandos 77, 78y 79en un comando, ¿existe un atajo para esto? Lo he intentado !77 !78 !79, lo que simplemente los colocará a todos en una sola línea para ejecutar.

MrDuk
fuente
99
Esta !77 ; !78 ; !79bien?
thrig
1
Supongo que cualquier cosa menos que escribir línea por línea está bien, pero esperaba algo un poco más conciso (en la línea de !77-79)
MrDuk
1
@ MrDuk, chico, eso me llevó un tiempo recordar. ¡Vea mi respuesta actualizada para la solución muy concisa ! :)
Comodín
¡Es mágico! :)
MrDuk

Respuestas:

28

EDITAR: puede hacer esto de manera compatible con POSIX con la herramienta de comando de reparaciónfc :

fc 77 79

Esto abrirá su editor (probablemente vi) con los comandos 77 a 79 en el búfer. Cuando guarde y salga ( :x), se ejecutarán los comandos.


Si no desea editarlos y está MUY SEGURO de saber a qué comandos está llamando, puede usar:

fc -e true 77 79

Esto se usa truecomo un "editor" para editar los comandos, por lo que simplemente sale sin hacer ningún cambio y los comandos se ejecutan tal cual.


RESPUESTA ORIGINAL:

Puedes usar:

history -p \!{77..79} | bash

Esto supone que no está utilizando ningún alias o funciones ni ninguna variable que solo esté presente en el entorno de ejecución actual, ya que, por supuesto, no estarán disponibles en el nuevo shell que se está iniciando.


Una mejor solución (gracias a Michael Hoffman por recordarme en los comentarios) es:

eval "$(history -p \!{77..79})"

¡Uno de los muy, muy pocos casos donde evales realmente apropiado!


Ver también:

Comodín
fuente
2
Esto no funcionará correctamente si alguno de los comandos cambia el entorno de ejecución actual, por ejemplo, cambiando una variable o haciendo un cd, pero ese es un caso marginal.
G-Man dice 'reinstalar a Monica' el
3
eval "$(history -p \!{77..79})"Deberia trabajar.
Michael Hoffman
1
@MichaelHoffman, pensé en eso y pensé que lo había intentado, ¡pero me di cuenta de que no mencioné! D'oh! No es de extrañar que no funcionó ... editando la respuesta ahora.
Comodín
14

Respuesta simple: en lugar de !77 !78 !79,

  • escriba !77; !78; !79para hacer lo que parece estar intentando hacer: ejecute el comando 77, y luego el comando 78, y luego el comando 79, incondicionalmente, o
  • escriba !77 && !78 && !79 para ejecutar el comando 77 y verifique si tuvo éxito. Y luego, si el comando 77 tuvo éxito, ejecute el comando 78. Y luego, si el comando 78 tuvo éxito, ejecute el comando 79.

Respuesta ligeramente más inteligente (si está en una ventana de tipo terminal):

  • Averigua qué número de comando será el siguiente comando que escribas.
    • Es posible incluir esto en su solicitud; Creo que es incluyéndolo \!en tu PS1.
    • O mira tu lista de historial. Si la última entrada es 82 history, entonces su próximo comando es 83.
  • Restar 83−77 = 6.
  • Tipo !-6. Esto volverá a ejecutar el comando 77.
  • Seleccione !-6, cópielo y péguelo. Como su nueva ejecución del comando 77 ( ./generator.sh) era el comando 83, ahora está en el comando 84, por !-6lo que volverá a ejecutar el comando 78.
  • Repita el pegado !-6como desee.
G-Man dice 'restablecer a Monica'
fuente