Wie kopiere ich eine ganze Kommandozeile ohne die Maus in meine Zwischenablage?

20

Stellen Sie sich vor, ich habe diese Zeile in meinem Terminal:

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

Nach dem Testen möchte ich diese Zeile in meine Zwischenablage kopieren und in eine Skriptdatei einfügen. Nicht die Ausgabe des Befehls . Aber dies ohne die Maus zu tun. Ich behalte meine Hände nur an der Tastatur. Ich denke, das geht schneller, um etwas zu programmieren :)

Valter Silva
quelle

Antworten:

22

Meine Antwort bietet einen einfachen Befehl in drei verschiedenen Syntaxen, die alle gleich funktionieren, aber eine ist etwas kürzer und einfacher zu tippen als die zweite. Die dritte Variante ist ein sogenannter Alias, dh Sie können dem Befehl einen benutzerdefinierten Namen zuweisen und ihn aufrufen, indem Sie diesen ausführen, ohne sich an die komplexen Dinge erinnern zu müssen.

Vorbereitung:

Installieren Sie zunächst das Paket xsel, mit dem Sie vom Terminal aus auf die X-Zwischenablage zugreifen können:

sudo apt-get install xsel

Befehlsvariante 1 (kurz):

Danach können Sie die folgende Zeile eingeben, um den vorherigen Befehl in die Zwischenablage zu kopieren:

xsel -ib <<<!!:q

Wenn Sie den zweitletzten Befehl kopieren möchten, ersetzen Sie ihn !!durch !-2, für die drittletzte Verwendung !-3usw.

Um zu erklären, was Sie gerade ausführen, hier eine kurze Aufschlüsselung des Befehls:

  • xselist ein Befehlszeilentool für den Zugriff auf die X-Zwischenablage.
    Weitere Informationen finden Sie in der Manpage onlineManpage-Symbol oder durch Ausführen man xsel.

    • Der -iParameter fordert xselzum Lesen von der Standardeingabe auf (normalerweise bedeutet dies Tastatureingabe, aber wir leiten hier etwas um)
    • Der -bParameter gibt an, dass die Zwischenablage anstelle der "primären" oder "sekundären" Auswahl von X verwendet werden soll.
  • <<<ist eine spezielle Bash-Syntax namens "Here String".
    Grundsätzlich wird das Argument (nur eines!) Danach erweitert (nicht ausgewertet!) Und als String an die Standardeingabe des Befehls weitergeleitet, bevor / nach dem es steht.

  • !!:qwird als "Knallbefehl" für die Erweiterung der Historie in Bash bezeichnet. Es ersetzt sich durch eine zuvor eingegebene Befehlszeile.
    Weitere Informationen finden Sie in der lokalen Manpage, indem Sie sie ausführen man history(die Online-Manpage ist nicht hilfreich).

    • Das !!steht für die vorherige Kommandozeile und ist ein Synonym für !-1.
      Offensichtlich !-2bedeutet das dann die vorletzte Kommandozeile. Vergessen Sie nicht das Minuszeichen -, sonst wird der 2. (3. / ...) Befehl zurückgegeben, den Sie jemals eingegeben haben.
    • Das :qändert den Befehl bang und weist bash an, die Ersetzung in einfache Anführungszeichen ( ') zu setzen, um eine weitere Erweiterung durch die Shell zu verhindern.

Befehlsvariante 2 (etwas länger):

echo !!:q | xsel -ib
  • echo hat die einfache Aufgabe, alle Argumente auf die Standardausgabe des Terminals zu drucken.

  • !!:qwird ein "Knallbefehl" für die Erweiterung der Historie in Bash genannt. Es ersetzt sich durch eine zuvor eingegebene Befehlszeile.

    • Das !!steht für die vorherige Kommandozeile und ist ein Synonym für !-1. Offensichtlich !-2heißt dann die vorletzte Kommandozeile. Vergessen Sie nicht das Minuszeichen -, sonst wird der 2. (3. / ...) Befehl zurückgegeben, den Sie jemals eingegeben haben.
    • Das :qändert den Befehl bang und weist bash an, die Ersetzung in einfache Anführungszeichen ( ') zu setzen, um eine weitere Erweiterung durch die Shell zu verhindern.
  • |ist eine Pfeife. Er leitet die Terminalausgabe ("stdout") des Befehls vor dem Befehl an die Terminaleingabe ("stdin") des Befehls nach dem Befehl weiter.

  • xselist ein Befehlszeilentool für den Zugriff auf die X-Zwischenablage.
    Weitere Informationen finden Sie in der Manpage onlineManpage-Symbol oder durch Ausführen man xsel.

    • Der -iParameter fordert xselzum Lesen von der Standardeingabe auf (normalerweise bedeutet dies Tastatureingabe, aber wir leiten hier etwas um)
    • Der -bParameter gibt an, dass die Zwischenablage anstelle der "primären" oder "sekundären" Auswahl von X verwendet werden soll.

Befehlsvariante 3 (Alias):

Ein Bash-Alias ​​ist eine coole Sache, wenn Sie sich nicht an lange oder komplizierte Befehle erinnern möchten, die Sie häufig verwenden. Sie können diesen Befehl einem einfachen Aliasnamen zuweisen, den Sie anstelle des langen Befehls ausführen können, um dasselbe zu erreichen.

Da Bang-Befehle eine spezielle Bash-Funktion sind und vor dem Auflösen von Aliasen erweitert werden, können Sie eine der oben genannten Variationen nicht einfach als Alias ​​kennzeichnen, da das !!Teil nicht funktioniert. Es gibt jedoch eine Problemumgehung.

Führen Sie zum Festlegen des Alias ​​die folgende Zeile in Ihrem Terminal aus. Beachten Sie, dass Sie einen beliebigen gültigen Bash-Variablennamen anstelle von copylastcommand:

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

Dies ist jedoch nur für Ihre aktuelle Bash-Sitzung so, dass der Alias ​​verschwindet, nachdem Sie das Terminalfenster geschlossen haben. Sie können es in jeder Ihrer Bash-Sitzungen persistent machen, indem Sie diese Zeile oben am Ende Ihrer ~/.bashrcDatei oder in Ihre ~/.bash_aliasesDatei einfügen, falls Sie eine haben.

Wieder eine kurze Pause von der Linie:

  • alias name='command'ist die Syntax zum Festlegen eines Alias ​​in Bash. Der commandwird immer dann ausgeführt, wenn Sie ihn namevon nun an ausführen .

  • history -p \!\!gibt die zuvor ausgeführte Kommandozeile an stdout aus (Standardausgabe). Ohne den -pSchalter würde der Befehl nicht nur gedruckt, sondern auch erneut ausgeführt.
    Beachten Sie, dass wir die Bangs ( !) mit Backslashes ( \) umgehen müssen , da Bash sie sonst erweitern würde, wenn wir versuchen, den Alias ​​festzulegen. Dies macht keinen Sinn, da sie so im Alias ​​sein müssen, wie sie sind.
    Sie können auch hier den [n] -ten Befehl angeben, indem Sie den zweiten Knall durch -nz \!-2.

  • |ist eine Pfeife. Es leitet die Standardausgabe ("stdout") des Befehls vor dem Befehl an den Terminalstandard ("stdin") des Befehls nach dem Befehl um.

  • xselist ein Befehlszeilentool für den Zugriff auf die X-Zwischenablage.
    Weitere Informationen finden Sie in der Manpage onlineManpage-Symbol oder durch Ausführen man xsel.

    • Der -iParameter fordert xselzum Lesen von der Standardeingabe auf (normalerweise bedeutet dies Tastatureingabe, aber wir leiten hier etwas um)
    • Der -bParameter gibt an, dass die Zwischenablage anstelle der "primären" oder "sekundären" Auswahl von X verwendet werden soll.
Byte Commander
quelle
1
Schöne Antwort, aber könnten Sie die Pfeife vermeiden? Bitte schön <<<"!!" xsel -ib
Kos
@kos ja danke Das macht es ein bisschen einfacher. Können Sie mir helfen, mich daran zu erinnern, wie die <<<Struktur erneut aufgerufen wird? Und ich denke, es <<<!!:q xsel -ibist besser (lassen Sie das History-Bang-Kommando zitieren), oder sind Sie anderer Meinung?
Byte Commander
Aber !!:qnutzt einfache Anführungszeichen ( ') ...
Byte Kommandant
Sie haben Recht, die Erweiterung würde mit ausgeführt <<<"!!" xsel -ib. Ja, <<<!!:q xsel -ibist besser, mach es.
Kos
Schön, xselhat interessante Syntax
Sergiy Kolodyazhnyy
5

Sie können verwenden xclip:

some_command | xclip -selection c

Also in deinem Fall:

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

c steht für Zwischenablage.

Möglicherweise müssen Sie xclipzuerst installieren :

sudo apt-get install xclip

BEARBEITEN:

Wenn Sie nur den von Ihnen eingegebenen Befehl (nicht die Ausgabe) in die Zwischenablage kopieren möchten, können Sie Here-Zeichenfolgen verwenden:

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

Oder eine Pfeife:

echo foobar | xclip -selection c
heemayl
quelle
1
Ich bekomme immer noch die Befehle ausgegeben, aber ich möchte nur die Zeile selbst.
Valter Silva
echo "command" | xclip -selection clipboard... Oder macht es zu einem Skript unter~/.bin : echo "$@" | xclip -selection clipboard. Angenommen, Sie speichern es als "cpy", dann könnten Sie cpy youtube-dl stuffund es würde in die Zwischenablage kopiert, ohne ausgeführt zu werden.
Alex
Und wenn Sie wollen, dass es ausgeführt wird ... echo "$@" | xclip -selection c && $@oder etwas Klügeres mit eval ...
Alex
@ WalterHenrique Bitte überprüfen Sie meine Änderungen ..
Heemayl
3

Ich habe gerade ein kleines Skript dafür erstellt zsh, das xclipdies ermöglicht:

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

Dieses Skript kopiert den letzten Befehl, der in der Shell / im Terminal eingegeben wurde, in die Zwischenablage des Systems. Auf einem typischen Remote-Server würde das nicht funktionieren.

Ich dachte, ich würde nur ein paar Minuten brauchen, um dieses Drehbuch zu schreiben, aber es dauerte überraschend lange, bis es funktionierte, als ich über den Umgang zshmit der Geschichte stolperte .

Die tail -n 2und Ersten sedbefassen sich mit der Tatsache, dass der Befehl für dieses Skript selbst im Verlauf aufgezeichnet wird und daher zwei Zeilen des Verlaufs abruft und die letzte entfernt.

Dieses Skript funktioniert, und es war eine Art lustiges Puzzle, aber ich bin wirklich gespannt, ob es eine einfachere oder elegantere Art gibt, dies zu tun zsh.

alec
quelle
Nun, Sie könnten wahrscheinlich die Befehle tailund sedin ein oder zwei Befehle vereinfachen . Diejenigen Befehle verwenden , !!die erklärt hier - es sollte in ZSH .... verfügbar sein
Wilf
Oh, in der !!Tat sieht es so aus, als wäre es hier hilfreich, danke!
Alec
0

Ich benutze als Zwischenablage-Manager, so.

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

Letzter Befehl in die Zwischenablage

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

Zwischenablage zum Verkratzen

alias vcb='pbpaste | vimscratch -'

ZSH spezifisch

# 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

Ich denke, diese Ideen können Ihnen helfen, Ihre eigene Lösung zu erstellen

SergioAraujo
quelle