¿Cómo copiar una línea de comando completa a mi portapapeles, sin el mouse?

20

Imagina que tengo esta línea en mi terminal:

youtube-dl --get-thumbnail --extract-audio --audio-format mp3 https://www.youtube.com/watch?v=

Después de probarlo, me gustaría copiar esta línea arriba en mi portapapeles y pegarla en algún archivo de script. No es la salida del comando . Pero, hacer esto sin usar el mouse. Me gusta mantener mis manos solo en el teclado. Creo que es más rápido de esa manera, hacer algo de codificación :)

Valter Silva
fuente

Respuestas:

22

Mi respuesta ofrece un comando simple en tres sintaxis diferentes, que funcionan todas por igual, pero una es un poco más corta y más fácil de escribir que la segunda. La tercera variación es un llamado alias, lo que significa que puede asignar al comando un nombre personalizado y llamarlo ejecutándolo sin tener que recordar las cosas complejas.

Preparación:

Primero, instale el paquete xselque le permite acceder al portapapeles X desde la terminal:

sudo apt-get install xsel

Variación de comando 1 (corta):

Después de eso, puede escribir la siguiente línea para copiar el comando anterior en el portapapeles:

xsel -ib <<<!!:q

Si desea copiar el segundo último comando, reemplácelo !!con !-2, para el tercer último uso, !-3etc.

Para explicar lo que está ejecutando, aquí un breve desglose del comando:

  • xseles una herramienta de línea de comandos para acceder a los portapapeles X.
    Para obtener más información, lea su página de manual en líneaIcono de página de manual o ejecutándose man xsel.

    • El -iparámetro le dice xselque lea desde el stdin (generalmente esto significa entrada de teclado, pero vamos a redirigir algo aquí)
    • El -bparámetro especifica usar el portapapeles en lugar de las selecciones "primarias" o "secundarias" de X.
  • <<<es una sintaxis especial de Bash llamada "Here String".
    Básicamente expande (¡no evalúa!) El argumento (¡solo uno!) Después de él y lo redirige como cadena al stdin (entrada estándar) del comando antes / después del cual se encuentra.

  • !!:qse llama "comando de explosión" para la expansión de la historia en bash. Se reemplaza con cualquier línea de comando previamente escrita.
    Para obtener más información, lea su página de manual local ejecutando man history(la página de manual en línea no es útil).

    • El !!representa la línea de comandos anterior y es sinónimo de !-1.
      Obviamente !-2significa entonces la segunda última línea de comando. No olvide el signo menos -; de lo contrario, devolverá el segundo comando (tercero / ...) que haya escrito.
    • Los :qmodifica el comando Bang y le indica a Bash para encerrar la sustitución entre comillas simples ( ') para evitar una mayor expansión de la cáscara.

Variación de comando 2 (un poco más larga):

echo !!:q | xsel -ib
  • echo tiene el simple trabajo de imprimir todos sus argumentos en la salida estándar del terminal.

  • !!:qse llama "comando de explosión" para la expansión de la historia en bash. Se reemplaza con cualquier línea de comando escrita anteriormente.

    • El !!representa la línea de comandos anterior y es sinónimo de !-1. Obviamente !-2significa entonces la segunda última línea de comando. No olvide el signo menos -; de lo contrario, devolverá el segundo comando (tercero / ...) que haya escrito.
    • Los :qmodifica el comando Bang y le indica a Bash para encerrar la sustitución entre comillas simples ( ') para evitar una mayor expansión de la cáscara.
  • |Es una pipa. Redirige la salida del terminal ("stdout") del comando anterior a la entrada del terminal ("stdin") del comando posterior.

  • xseles una herramienta de línea de comandos para acceder a los portapapeles X.
    Para obtener más información, lea su página de manual en líneaIcono de página de manual o ejecutándose man xsel.

    • El -iparámetro le dice xselque lea desde el stdin (generalmente esto significa entrada de teclado, pero vamos a redirigir algo aquí)
    • El -bparámetro especifica usar el portapapeles en lugar de las selecciones "primarias" o "secundarias" de X.

Variación de comando 3 (alias):

Un alias bash es genial si no quieres recordar comandos largos o complicados que usas con frecuencia. Puede asignar este comando a un nombre de alias simple, que puede ejecutar en lugar del comando largo para lograr el mismo.

Desafortunadamente, dado que los comandos de explosión son una característica especial de Bash y se expanden antes de que se resuelvan los alias, no puede simplemente alias una de las variaciones anteriores porque la !!parte no funcionará. Sin embargo, hay una solución alternativa.

Para configurar el alias, ejecute la siguiente línea en su terminal. Tenga en cuenta que puede elegir cualquier nombre de variable Bash válido en lugar de copylastcommand:

alias copylastcommand='history -p \!\! | xsel -ib'

Sin embargo, esto solo es persistente para su sesión de Bash actual, lo que significa que el alias desaparecerá después de cerrar la ventana de terminal. Puede hacerlo persistente en cada una de sus sesiones de Bash agregando esta línea arriba al final de su ~/.bashrcarchivo, o a su ~/.bash_aliasesarchivo si tiene una.

Una vez más, un breve desglose de la línea:

  • alias name='command'es la sintaxis para establecer un alias en Bash. El commandse ejecutará siempre que ejecute a namepartir de ahora.

  • history -p \!\!envía la línea de comando ejecutada previamente a stdout (salida estándar). Sin el -pinterruptor, no solo imprimiría, sino que también volvería a ejecutar el comando.
    Tenga en cuenta que debemos escapar del flequillo ( !) con barras invertidas ( \), porque de lo contrario bash los expandiría cuando intentemos establecer el alias, lo que no tiene sentido ya que deben estar en el alias tal como están.
    Una vez más, también puede especificar el comando [n] -th reciente reemplazando el segundo golpe con -n, p \!-2. Ej .

  • |Es una pipa. Redirige la salida estándar ("stdout") del comando anterior al estándar de terminal ("stdin") del comando posterior.

  • xseles una herramienta de línea de comandos para acceder a los portapapeles X.
    Para obtener más información, lea su página de manual en líneaIcono de página de manual o ejecutándose man xsel.

    • El -iparámetro le dice xselque lea desde el stdin (generalmente esto significa entrada de teclado, pero vamos a redirigir algo aquí)
    • El -bparámetro especifica usar el portapapeles en lugar de las selecciones "primarias" o "secundarias" de X.
Byte Commander
fuente
1
Buena respuesta, pero ¿podrías evitar la pipa? ¿Bastante por favor? <<<"!!" xsel -ib
kos
@kos sí, gracias. Eso lo hace un poco más fácil. ¿Podrías ayudarme a recordar cómo <<<se llama de nuevo a la estructura? Y creo que <<<!!:q xsel -ibes mejor (dejar que el comando de explosión histórica haga la cita), ¿o no está de acuerdo?
Byte Commander
Pero !!:qusa comillas simples ( ') ...
Byte Commander
Tienes razón, la expansión se realizaría usando <<<"!!" xsel -ib. Sí, <<<!!:q xsel -ibes mejor, adelante.
kos
Agradable, xseltiene una sintaxis interesante
Sergiy Kolodyazhnyy
5

Puedes usar xclip:

some_command | xclip -selection c

Entonces en tu caso:

youtube-dl .... | xclip -selection c

c significa portapapeles.

Es posible que deba instalar xclipprimero:

sudo apt-get install xclip

EDITAR:

Si solo desea que el comando que ha escrito (no el resultado) se copie en el portapapeles, puede usar las cadenas Aquí:

 xclip -selection c <<<"$(echo foobar)"

O una pipa:

echo foobar | xclip -selection c
heemayl
fuente
1
Todavía obtengo los resultados de los comandos, pero solo quiero la línea en sí.
Valter Silva
echo "command" | xclip -selection clipboard... O lo convierten en un guión bajo~/.bin : echo "$@" | xclip -selection clipboard. Digamos que lo guarda como "cpy", entonces podría cpy youtube-dl stuffy se copiaría al portapapeles sin ser ejecutado.
Alex
Y si quieres que se ejecute ... echo "$@" | xclip -selection c && $@, o algo más inteligente con eval ...
Alex
@ValterHenrique Por favor revise mis ediciones ..
heemayl 01 de
3

Acabo de hacer un pequeño script para zsheso que se usa xclippara hacer esto:

#!/bin/zsh
export HISTFILE=~/.zsh_history
fc -R
fc -l | tail -n 2 | sed -n '1p' | sed 's/[0-9]*  //' | xclip -selection c

Este script copia el último comando que se ingresó en el shell / terminal al portapapeles del sistema. No funcionaría en un servidor remoto típico.

Pensé que me tomaría solo un par de minutos escribir este guión, pero me tomó sorprendentemente mucho tiempo hacerlo funcionar mientras tropezaba con la forma en que zshmaneja la historia.

El tail -n 2primero y el primero sedes tratar con el hecho de que el comando para este script en sí mismo se está registrando en el historial y, por lo tanto, obtiene dos líneas del historial y elimina el último.

Este script funciona, y fue una especie de rompecabezas divertido, pero tengo mucha curiosidad si hay una manera más simple o más elegante de hacerlo zsh.

alec
fuente
Bueno, probablemente podría simplificar los comandos taily seden uno o dos comandos. Esos comandos usan lo !!que se explica aquí : debería estar disponible en ZSH ...
Wilf
Oh, de !!hecho parece que sería útil aquí, ¡gracias!
alec
0

Estoy usando como administrador del portapapeles, entonces.

alias pbpaste='xclip -i -selection clipboard -o'
alias pbcopy='xclip -selection clipboard'
vimscratch='vim -c 'setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile' 

Último comando al portapapeles

alias last2cb='fc -ln -1 | pbcopy'

Portapapeles para rayar vim

alias vcb='pbpaste | vimscratch -'

ZSH específico

# Copy the most recent command to the clipboard
function _pbcopy_last_command(){
    fc -ln -1 | pbcopy
}
zle -N pbcopy-last-command _pbcopy_last_command
bindkey '^x^y' pbcopy-last-command
# Ctrl-x Ctrl-y  to copy last command to the clipboard


# Edit content of clipboard on vim (scratch buffer)
function _edit_clipboard(){
    pbpaste | vim -c 'setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile' -
}
zle -N edit-clipboard _edit_clipboard
bindkey '^x^v' edit-clipboard
# Ctrl-x Ctrl-v to edit clipboard on vim


# define function that retrieves and runs last command
function run-again {
    # get previous history item
    zle up-history
    # confirm command
    zle accept-line
}
# define run-again widget from function of the same name
zle -N run-again
bindkey '\er' run-again
# alt-r to run last command again

Creo que estas ideas pueden ayudarte a crear tu propia solución

SergioAraujo
fuente