Befehl zum Einfügen meines Befehls und seiner Ausgabe

9

Oft möchte ich etwas in einem Github-Bug wie posten

$ ping google.com
PING google.com (216.58.195.238): 56 data bytes
Request timeout for icmp_seq 0
64 bytes from 216.58.195.238: icmp_seq=0 ttl=53 time=1064.747 ms

Im Moment führe ich den Befehl aus, benutze screen's C-a C-[, um den Bereich hervorzuheben, enterum ihn in diesen Puffer zu kopieren, in ihn einzufügen, vimin eine Datei zu schreiben und dann catin pbcopy. Es muss einen besseren Weg geben.

Gibt es einen Befehl, den ich ausführen kann, dem teeder von mir eingegebene Befehl ein $und die gesamte Ausgabe vorangestellt wird pbcopy? Oder irgendetwas in der Nähe? Ich stelle mir vor

$ demo ping google.com
PING google.com (216.58.195.238): 56 data bytes
Request timeout for icmp_seq 0
64 bytes from 216.58.195.238: icmp_seq=0 ttl=53 time=1064.747 ms
^C
$

und jetzt ist das Original, das ich eingefügt habe, in meiner Mac-Zwischenablage.

Paul Tarjan
quelle
Ist das wirklich spezifisch für OS X?
Phk
Nee. Welches Dienstprogramm Sie auch verwenden, um von einer Datei in eine Zwischenablage auf anderen Plattformen zu wechseln, könnte ersetzt werden, pbcopyund es wäre dieselbe Frage.
Paul Tarjan
2
Neugierig: Warum benutzt du nicht die Maus?
2
Sie können den gesamten Vim-Teil weglassen. Einfach rennen pbcopyund C-a C-]loslegen.
@hop mit der Maus ist langsam und funktioniert nicht gut, wenn es mehrere Bildschirme mit Text gibt
Paul Tarjan

Antworten:

10

Eine Möglichkeit besteht darin, die Ablaufverfolgung (mit -x) in einer Subshell zu aktivieren, in der der Befehl ausgeführt wird. Dies schreibt den Befehl in STDERR und die Standardausgabe in STDOUT. Sammeln Sie beide und leiten Sie an pbcopy:

$ ( set -x; ping -c 3 google.com ) 2>&1 | pbcopy

$ pbpaste
+ ping -c 3 google.com
PING google.com (173.194.217.138): 56 data bytes
64 bytes from 173.194.217.138: icmp_seq=0 ttl=44 time=37.436 ms
64 bytes from 173.194.217.138: icmp_seq=1 ttl=44 time=38.891 ms
64 bytes from 173.194.217.138: icmp_seq=2 ttl=44 time=39.329 ms
--- google.com ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 37.436/38.552/39.329/0.809 ms
JRFerguson
quelle
set -xist ein interessanter Ansatz. Gut erkannt!
DopeGhoti
Ich würde gerne auch meinen Befehl ausdrucken sehen (vorzugsweise noch in 2 verschiedenen Streams) und würde es gerne +sein$
Paul Tarjan
1
@PaulTarjan: dann PS4 entsprechend ändern. Ein Beispiel (nicht das, was Sie brauchen, zeigt aber einige mögliche Optionen) : PS4='\\$ ${BASH_SOURCE[0]:-inherited}:line ${LINENO}:${FUNCNAME[0]:+${FUNCNAME[0]}(): } '. Das "\\ $" macht "$" zum ersten Zeichen, und dieses Zeichen wird dann wiederholt, um die Anrufstufe anzuzeigen. ($ für die erste Ebene, $$ für die zweite Ebene usw.)
Olivier Dulac
7

Mit dem scriptDienstprogramm können Sie die gesamte Interaktion einschließlich Ihrer Eingabeaufforderung, Ihres Befehls und ihrer Ausgabe erfassen:

script temp.log; cat temp.log | pbcopy
[ do stuff ]
[ end the interaction with ^D or logging out of the shell ]

Sie können die Datei dann überprüfen, und ihr Inhalt befindet sich bereits in Ihrer Zwischenablage.

Du kannst auch:

script temp.log 'somecommand'; cat temp.log | pbcopy
DopeGhoti
quelle
Das ist nah. Es enthielt meine gesamte Eingabeaufforderung, wo ich nur eine möchte, $ und es ermöglicht mir, viele Befehle auszuführen, bei denen ich nur eine möchte, und es fügt eine Kopf- und Fußzeile hinzu, die ich nicht möchte.
Paul Tarjan
1
Ich denke nicht, dass es ANSI-Sequenzen unterdrücken kann (da es beabsichtigt ist, die gesamte Sitzung zu erfassen), aber Sie können den Header unterdrücken. Überprüfen Sie die Manpage auf -q. Sie können verwenden sed, um die ANSI-Codes zu sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"
entfernen
2
Sie können verwenden script temp.log env PS1='$ ' bash --norc, um eine Bash mit der gewünschten Eingabeaufforderung zu erhalten. Alternativ können Sie Ihre bearbeiten ~/.bashrc, um die Verwendung zu überprüfen scriptund die Eingabeaufforderung zu ändern:[ $(ps -o command= -p $PPID) = 'script' ] && PS1='$ '
Eric
1

Aufgrund Ihres Kommentars zu einer anderen Antwort möchten Sie nicht, dass Ihre gesamte Eingabeaufforderung kopiert wird, sondern nur $.

Wie ich das löse, ist einfach:

16:54:53 [myname mydirectory] 535 $ bash
bash-3.2$ PS1='\$ '
$ echo some command
some command
$ exit
exit
16:57:17 [myname mydirectory] 536 $

Einfach. Dann benutze ich die Maus, um die gewünschte Eingabeaufforderung, den Befehl und die Ausgabe zu kopieren und einzufügen.


Für einen anderen Anwendungsfall, in dem ich nur möchte, dass der Befehl, nicht seine Ausgabe und nicht die Eingabeaufforderung, jemandem Anweisungen geben kann, habe ich einen Alias ​​eingerichtet zv(in der Nähe von "Befehl V" auf der Tastatur), um den Befehl zu kopieren letzter Befehl in meine Zwischenablage :

alias zv='printf %s "$(history -p \!\!)" | pbcopy'

Beachten Sie die Verwendung von printfund die Ersetzung von Befehlen, um zu vermeiden, dass die nachfolgende neue Zeile historyin die Zwischenablage aufgenommen wird.

Platzhalter
quelle
0

Im Moment führe ich den Befehl aus, benutze das Ca C- [des Bildschirms, um den Bereich hervorzuheben, drücke ein, um ihn in diesen Puffer zu kopieren.

Wenn Sie bereits verwenden GNU screen, können Sie eine Auswahl direkt mit einem externen Tool kopieren. Zum Beispiel habe ich dies ~/.screenrcunter Linux hinzugefügt :

bind b eval writebuf 'exec /bin/sh -c " xsel -i </tmp/screen-exchange"' 'exec /bin/sh -c "killall xsel"'

Jetzt kann ich eine Auswahl mit Control- markieren a [, drücken Spaceund jetzt drücken Control- a bum auszuführen xsel. Es ist nicht meine Idee, es ist eigentlich ziemlich häufig . Beachten Sie, dass einige Leute es pbcopystattdessen verwenden,xsel damit es problemlos für Sie funktioniert.

Arkadiusz Drabczyk
quelle