¿Cómo obtener rápidamente la salida de línea anterior en un terminal sin usar un mouse?


13

Terminal de Linux (por ejemplo, Ubuntu), ¿hay algún método para obtener la última línea? Digamos que estoy escribiendo aleatoriamente un tdcomando, que no se ha instalado en mi sistema, por lo que recibiré un mensaje como el siguiente. Me gustaría tener un "atajo" para correr sudo apt-get install textdrawrápidamente.

¿Existe tal herramienta o cómo puedo copiar la última línea al portapapeles sin usar el mouse?

username@WorkStation:~$ td
The program 'td' is currently not installed. You can install it by typing:
sudo apt-get install textdraw
username@WorkStation:~$

Presione la flecha hacia arriba? ¿Has intentado eso? También revise el comando de historial en Linux, que también podría funcionar para usted.
Richie086

Los programas de multiplexor de terminal, tmux y pantalla, brindan la capacidad de obtener texto en un portapapeles. Sin embargo, puede haber una manera más fácil en la GUI predeterminada de Ubuntu, por lo que sospecho que una respuesta más fácil puede estar disponible. Presionar PgUp, Shift-PgUp o Ctrl-PgUp podría permitir el desplazamiento hacia atrás.
TOOGAM

3
@ Richie086 Tenga en cuenta que lo que necesito es que sudo apt-get install textdrawno td. la flecha hacia arriba solo me dará eltd
Daniel

Respuestas:


6

Si no te importa un poco de obscenidad (no me importa), es posible que desees usar la mierda , una herramienta que hace exactamente lo que pediste.

Bueno, no exactamente, pero resuelve el mismo problema. En lugar de obtener la última línea, intenta hacer coincidir el último comando que escribió.

Fuck intenta hacer coincidir una regla con el comando anterior, crea un nuevo comando utilizando la regla coincidente y lo ejecuta.

Los ejemplos que se muestran en el repositorio muestran varios de los escenarios que mencionó.

ingrese la descripción de la imagen aquí


2

La respuesta corta: no, probablemente no tenga un método disponible para hacerlo.

La respuesta larga:

  • mientras es posible tener un emulador de terminal que le permite "simplemente" volver a leer el contenido de la pantalla y editarlo, en la práctica eso no se hace con frecuencia debido a la preocupación de que algún programa no deseado pueda espiar las entradas de su teclado.
  • una cáscara podría diseñar capturar la salida de sus comandos y permitirle editar eso (al igual que su historial de comandos). Sería complicado si el comando fuera algo así vi(donde el resultado no es un texto orientado a líneas agradable). bash no hace eso, de todos modos.

En la práctica, lo que la gente hace para solucionar esta limitación es usar otros programas para capturar el resultado del comando y editarlo. Pero no resolverá su problema inmediato.

Por ejemplo, uso vi-like-emacs para emitir comandos de shell ad hoc. Si esos no requieren más información, funciona bien ejecutarlos en una ventana , capturar la salida del comando y editar la salida según sea necesario para refinar el comando. Emacs también te permite hacer algo así, así como vim.


2

Si recibió ese mensaje en ubuntu después de ejecutar un comando no existente desde bash, su sistema probablemente esté utilizando la command_not_found_handlefunción. Puedes verlo en /etc/bash.bashrc.

Una piratería trivial puede ser una opción: acabo de crear un script llamado cnfh:

#!/bin/bash

# if the command-not-found package is installed, use it
if [ -x /usr/lib/command-not-found -o -x /usr/share/command-not-found/command-not-found ]; then
        function command_not_found_handle {
                # check because c-n-f could've been removed in the meantime
                if [ -x /usr/lib/command-not-found ]; then
                   /usr/lib/command-not-found -- "$1"
                   return $?
                elif [ -x /usr/share/command-not-found/command-not-found ]; then
                   /usr/share/command-not-found/command-not-found -- "$1"
                   return $?
                else
                   printf "%s: command not found\n" "$1" >&2
                   return 127
                fi
        }
fi


"$@"
RET_VAL=$?
if [ $RET_VAL -eq 127 ]; then
  OUT=$(command_not_found_handle "$@" 2>&1)
  $(echo $OUT |sed -n 's/.*\(apt-get install .\+\)$/\1/p')
fi

Luego ejecute el comando td usando este script:

# ./cnfh td

Usando Ubuntu 14.04.2 LTS . Espero que eso ayude.


Esto se ve realmente genial y tal vez algo que me gustaría agregar a mi sistema. ¿Podría agregar alguna información sobre cómo funciona? El código incorporado para manejar finalizaciones y cosas como esta es bastante difícil de entender.
Joe

2

En tmux v2.4 y en adelante (ya que esto confirma https://github.com/tmux/tmux/commit/76d6d3641f271be1756e41494960d96714e7ee58 ) con send-keys -X. Puede ser posible en versiones anteriores, con una sintaxis diferente.

En .tmux.conf:

bind ! copy-mode \;\
       send-keys -X cursor-up \;\
       send-keys -X select-line \;\
       send-keys -X cursor-left \;\
       send-keys -X copy-selection-and-cancel \;\
       paste-buffer

Ahora, prefix+!copiará la última línea en la posición actual del cursor.

cursor-left puede omitirse si desea ejecutarlo directamente sin escribir return.

Nota : no funcionará si la última línea está vacía o si está envuelta, pero sigue siendo útil en la mayoría de los casos


1

Para ejecutar la última línea de salida del comando más reciente, si está dispuesto a volver a ejecutar ese comando (ya que no hizo nada excepto emitir un mensaje de diagnóstico), haga

$($(fc -ln -1) | tail -n 1)

Paso a paso (capa por capa):

  • fc (que podría significar "Arreglar comando") es un comando integrado de shell para acceder al historial de comandos.

    • -ln
      • l(minúscula L) - l ist comando (s) anterior (es)
      • n- no incluyen comandos n umbers
    • 1 (uno) - se refiere al comando más reciente

    fc -ln -1 enumera el comando más reciente, sin incluir un número de comando.

  • $(fc -ln -1) Ejecuta el comando más reciente.
  • $(fc -ln -1) | tail -n 1ejecuta el comando más reciente y muestra la última línea de su salida. Esta es la sudo apt-get install textdrawlínea, en tu ejemplo.
  • $($(fc -ln -1) | tail -n 1)ejecuta ese comando

Puedes alias esto:

alias execute_last_line_of_output_from_previous_command='$($(fc -ln -1) | tail -n 1)'

Te dejo elegir un nombre más corto para el alias.

Notas:

  • Esto sólo funciona para los comandos simples - no hay caracteres especiales como |, <, >, ;, &, o incluso frases. Si necesita manejar comandos complejos, probablemente pueda hacerlo agregando un eval, pero esto no es muy recomendable.
  • Si necesita acceder a algo que no sea la última línea de salida (por ejemplo, la última línea del decimoséptimo), puede hacer algo tail -n 17 | head -n 1.
  • Si necesita acceder a algo que no sea el comando más reciente, puede modificar los argumentos a fc. Tenga en cuenta que fc -ln -1es la abreviatura de fc -ln -1 -1. Para recuperar el tercer comando más reciente, usefc -ln -3 -3 .
  • Si necesita flexibilidad como la anterior, probablemente debería escribir una función de shell que tome argumentos en lugar de un alias.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.