Comment copier une ligne de commande entière dans mon presse-papiers, sans la souris?

20

Imaginez que j'ai cette ligne dans mon terminal:

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

Après l'avoir testé, je voudrais copier cette ligne ci-dessus dans mon presse-papiers et la coller dans un fichier de script. Pas la sortie de la commande . Mais, cela sans utiliser la souris. J'aime garder mes mains sur le clavier uniquement. Je pense que c'est plus rapide de cette façon, pour faire du codage :)

Valter Silva
la source

Réponses:

22

Ma réponse propose une commande simple dans trois syntaxes différentes, qui fonctionnent toutes également, mais l'une est un peu plus courte et plus facile à taper que la seconde. La troisième variante est un soi-disant alias, ce qui signifie que vous pouvez attribuer à la commande un nom personnalisé et l'appeler en l'exécutant sans avoir à vous souvenir des éléments complexes.

Préparation:

Tout d'abord, installez le package xselqui vous permet d'accéder au presse-papiers X depuis le terminal:

sudo apt-get install xsel

Variation de commande 1 (courte):

Après cela, vous pouvez taper la ligne suivante pour copier la commande précédente dans le presse-papiers:

xsel -ib <<<!!:q

Si vous souhaitez copier la deuxième commande la plus récente, remplacez-la !!par !-2, pour la troisième utilisation la plus récente !-3, etc.

Pour expliquer ce que vous exécutez, voici une brève ventilation de la commande:

  • xselest un outil en ligne de commande pour accéder aux presse-papiers X.
    Pour plus d'informations, lisez sa page de manuel en ligneIcône de page de manuel ou en exécutant man xsel.

    • Le -iparamètre indique xselde lire à partir du stdin (généralement cela signifie une entrée au clavier, mais nous allons rediriger quelque chose ici)
    • Le -bparamètre spécifie d'utiliser le presse-papiers au lieu des sélections "primaires" ou "secondaires" de X.
  • <<<est une syntaxe Bash spéciale appelée "Here String".
    Il développe (et n'évalue pas!) L'argument (un seul!) Après lui et le redirige en tant que chaîne vers le stdin (entrée standard) de la commande avant / après laquelle il se trouve.

  • !!:qest appelé une "commande de coup" pour l'expansion de l'historique dans bash. Il se remplace par n'importe quelle ligne de commande précédemment tapée.
    Pour plus d'informations, lisez sa page de manuel locale en exécutant man history(la page de manuel en ligne n'est pas utile).

    • Le !!représente la ligne de commande précédente et est un synonyme de !-1.
      Signifie évidemment !-2alors l'avant-dernière ligne de commande. N'oubliez pas le signe moins -, sinon il renverra la 2ème commande (3ème / ...) que vous avez déjà tapée.
    • Le :qmodifie la commande bang et dit à bash de placer la substitution entre guillemets simples ( ') pour empêcher une nouvelle expansion par le shell.

Variation de commande 2 (légèrement plus longue):

echo !!:q | xsel -ib
  • echo a pour tâche simple d'imprimer tous ses arguments sur la sortie standard du terminal.

  • !!:qest appelé une "commande de coup" pour l'expansion de l'historique dans bash. Il se remplace par n'importe quelle ligne de commande précédemment tapée.

    • Le !!représente la ligne de commande précédente et est un synonyme de !-1. Signifie évidemment !-2alors l'avant-dernière ligne de commande. N'oubliez pas le signe moins -, sinon il renverra la 2ème commande (3ème / ...) que vous avez déjà tapée.
    • Le :qmodifie la commande bang et dit à bash de placer la substitution entre guillemets simples ( ') pour empêcher une nouvelle expansion par le shell.
  • |est une pipe. Il redirige la sortie du terminal ("stdout") de la commande avant celle-ci vers l'entrée du terminal ("stdin") de la commande qui la suit.

  • xselest un outil en ligne de commande pour accéder aux presse-papiers X.
    Pour plus d'informations, lisez sa page de manuel en ligneIcône de page de manuel ou en exécutant man xsel.

    • Le -iparamètre indique xselde lire à partir du stdin (généralement cela signifie une entrée au clavier, mais nous allons rediriger quelque chose ici)
    • Le -bparamètre spécifie d'utiliser le presse-papiers au lieu des sélections "primaires" ou "secondaires" de X.

Variation de commande 3 (alias):

Un alias bash est une bonne chose si vous ne voulez pas vous souvenir des commandes longues ou compliquées que vous utilisez souvent. Vous pouvez attribuer cette commande à un nom d'alias simple, que vous pouvez exécuter à la place de la commande longue pour obtenir le même résultat.

Malheureusement, comme les commandes de coup sont une fonctionnalité spéciale de Bash et sont développées avant que les alias ne soient résolus, vous ne pouvez pas simplement alias l'une des variantes ci-dessus car la !!pièce ne fonctionnera pas. Il existe cependant une solution de contournement.

Pour définir l'alias, exécutez la ligne suivante dans votre terminal. Notez que vous pouvez choisir n'importe quel nom de variable Bash valide au lieu de copylastcommand:

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

Ceci n'est cependant que persistant pour votre session Bash actuelle, ce qui signifie que l'alias disparaîtra après la fermeture de la fenêtre du terminal. Vous pouvez le rendre persistant dans chacune de vos sessions Bash en ajoutant cette ligne ci-dessus à la fin de votre ~/.bashrcfichier, ou à votre ~/.bash_aliasesfichier si vous en avez un.

Encore une fois, une brève rupture de la ligne:

  • alias name='command'est la syntaxe pour définir un alias dans Bash. Le commandsera exécuté chaque fois que vous exécutez à namepartir de maintenant.

  • history -p \!\!renvoie la ligne de commande précédemment exécutée vers stdout (sortie standard). Sans le -pcommutateur, il imprimerait non seulement mais réexécuterait également la commande.
    Notez que nous devons échapper les bangs ( !) avec des barres obliques inverses ( \), car sinon bash les développerait lorsque nous essayons de définir l'alias, ce qui n'a aucun sens car ils doivent être dans l'alias tels qu'ils sont.
    Encore une fois, vous pouvez également spécifier la commande [n] -th récente en remplaçant le deuxième bang par -n, par exemple \!-2.

  • |est une pipe. Il redirige la sortie standard ("stdout") de la commande qui la précède vers la norme terminale ("stdin") de la commande qui la suit.

  • xselest un outil en ligne de commande pour accéder aux presse-papiers X.
    Pour plus d'informations, lisez sa page de manuel en ligneIcône de page de manuel ou en exécutant man xsel.

    • Le -iparamètre indique xselde lire à partir du stdin (généralement cela signifie une entrée au clavier, mais nous allons rediriger quelque chose ici)
    • Le -bparamètre spécifie d'utiliser le presse-papiers au lieu des sélections "primaires" ou "secondaires" de X.
Byte Commander
la source
1
Belle réponse, mais pourriez-vous éviter la pipe? Jolie s'il-vous-plaît? <<<"!!" xsel -ib
kos
@kos oui, merci. Cela rend les choses un peu plus faciles. Pourriez-vous aider mon esprit à se rappeler comment la <<<structure est appelée à nouveau? Et je pense que <<<!!:q xsel -ibc'est mieux (laisser la commande history bang faire la citation), ou êtes-vous en désaccord?
Byte Commander
Mais !!:qutilise des guillemets simples ( ') ...
Byte Commander
Vous avez raison, l'expansion serait effectuée en utilisant <<<"!!" xsel -ib. Oui, <<<!!:q xsel -ibc'est mieux, allez-y.
kos
Nice, xsela une syntaxe intéressante
Sergiy Kolodyazhnyy
5

Vous pouvez utiliser xclip:

some_command | xclip -selection c

Donc dans votre cas:

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

c signifie presse-papiers.

Vous devrez peut-être installer d' xclipabord:

sudo apt-get install xclip

ÉDITER:

Si vous souhaitez simplement que la commande que vous avez tapée (pas la sortie) soit copiée dans le presse-papiers, vous pouvez utiliser les chaînes Here:

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

Ou une pipe:

echo foobar | xclip -selection c
heemayl
la source
1
J'obtiens toujours la sortie des commandes, mais je veux juste la ligne elle-même.
Valter Silva
echo "command" | xclip -selection clipboard... Ou faire un script sous~/.bin : echo "$@" | xclip -selection clipboard. Supposons que vous l'enregistriez en tant que "cpy", alors vous pourriez cpy youtube-dl stuffet il serait copié dans le presse-papiers sans être exécuté.
Alex
Et si vous voulez qu'il soit exécuté ... echo "$@" | xclip -selection c && $@, ou quelque chose de plus intelligent avec eval ...
Alex
@ValterHenrique S'il vous plaît vérifier mes modifications ..
heemayl
3

Je viens de faire un petit script pour zshcela utilise xclippour le faire:

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

Ce script copie la dernière commande entrée dans le shell / terminal dans le presse-papiers du système. Cela ne fonctionnerait pas sur un serveur distant typique.

Je pensais que cela ne me prendrait que quelques minutes pour écrire ce script, mais il a fallu étonnamment de temps pour le faire fonctionner alors que je trébuchais sur la façon dont l' zshhistoire était gérée.

Le tail -n 2et le premier sedtraitent du fait que la commande pour ce script lui-même est enregistrée dans l'historique et qu'il obtient donc deux lignes d'historique et supprime la dernière.

Ce script fonctionne, et c'était une sorte de puzzle amusant, mais je suis vraiment curieux de savoir s'il existe une façon plus simple ou plus élégante de le faire zsh.

alec
la source
Eh bien, vous pourriez probablement simplifier les commandes tailet seden une ou deux commandes. Ces commandes utilisent !!ce qui est expliqué ici - il devrait être disponible dans ZSH ....
Wilf
Oh, en !!effet, il semble que ce serait utile ici, merci!
alec
0

J'utilise comme gestionnaire de presse-papiers, donc.

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

Dernière commande dans le presse-papiers

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

Presse-papiers pour vim scratch

alias vcb='pbpaste | vimscratch -'

Spécifique ZSH

# 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

Je pense que ces idées peuvent vous aider à créer votre propre solution

SergioAraujo
la source