Commande pour coller ma commande et sa sortie

9

Souvent, je veux publier quelque chose sur un bug Github comme

$ 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

En ce moment, j'exécute la commande, utilise screen's C-a C-[pour mettre la zone en surbrillance, enterpour la copier dans ce tampon, la coller dans vim, l'écrire dans un fichier et ensuite catdans pbcopy. Il doit y avoir une meilleure façon.

Existe-t-il une commande que je peux exécuter qui sera teela commande que je tape préfixée avec un $et toutes les sorties pbcopy? Ou quelque chose de proche? J'envisage

$ 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
$

et maintenant la chose originale que j'ai collée est dans mon presse-papiers mac.

Paul Tarjan
la source
Est-ce vraiment spécifique à OS X?
phk
Nan. Quel que soit l'utilitaire que vous utilisez pour passer d'un fichier à un presse-papiers sur d'autres plates-formes, il pourrait être remplacé pbcopyet ce serait la même question.
Paul Tarjan
2
Curieux: pourquoi n'utilisez-vous pas la souris?
2
Vous pouvez laisser de côté toute la partie vim. Exécutez simplement pbcopyet C-a C-]à son stdin.
@hop utilisant la souris est lent et ne fonctionne pas bien quand il y a plusieurs écrans de texte
Paul Tarjan

Réponses:

10

Une option consiste à activer le suivi (avec -x) dans un sous-shell qui exécute la commande. Cela écrit la commande dans STDERR et la sortie standard dans STDOUT. Récupérez les deux et canalisez pour 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
la source
set -xest une approche intéressante. Bien repéré!
DopeGhoti
J'aimerais aussi voir ma commande également imprimée (de préférence encore sur 2 flux différents), et j'aimerais +être$
Paul Tarjan
1
@PaulTarjan: changez ensuite la PS4 en conséquence. Un exemple (pas ce dont vous avez besoin, mais montre quelques options possibles): PS4='\\$ ${BASH_SOURCE[0]:-inherited}:line ${LINENO}:${FUNCNAME[0]:+${FUNCNAME[0]}(): } '. Le "\\ $" fait de "$" le premier caractère, et ce caractère est ensuite répété pour montrer le niveau d'appel. ($ pour le premier niveau, $$ pour le deuxième niveau, etc.)
Olivier Dulac
7

Vous pouvez utiliser l' scriptutilitaire pour capturer l'intégralité de l'interaction, y compris votre invite, commande et sa sortie:

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

Vous pouvez ensuite consulter le fichier et son contenu sera déjà dans votre presse-papiers.

Vous pouvez également:

script temp.log 'somecommand'; cat temp.log | pbcopy
DopeGhoti
la source
C'est proche. Il comprenait toute mon invite où je voulais juste un $ et cela me permet de faire de nombreuses commandes là où je n'en veux qu'un, et il ajoute un en-tête et un pied de page dont je ne veux pas.
Paul Tarjan
1
Je ne pense pas qu'il puisse supprimer les séquences ANSI (car par conception, il est là pour capturer la session entière), mais vous pouvez supprimer l'en-tête. Consultez la page de manuel pour -q. Vous pouvez utiliser sedpour sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"
supprimer
2
Vous pouvez utiliser script temp.log env PS1='$ ' bash --norcpour obtenir un bash avec l'invite souhaitée. Alternativement, vous pouvez modifier votre ~/.bashrcpour vérifier l'utilisation scriptet modifier l'invite:[ $(ps -o command= -p $PPID) = 'script' ] && PS1='$ '
Eric
1

D'après votre commentaire sur une autre réponse , vous ne voulez pas que toute votre invite soit copiée, mais seulement $.

Comment je résous ceci est simplement:

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

Facile. Ensuite, j'utilise la souris pour copier et coller l'invite, la commande et la sortie que je veux.


Pour un cas d'utilisation différent où je veux juste que la commande, pas sa sortie et pas l'invite, puisse donner des instructions à quelqu'un, j'ai mis en place un alias, zv(proche de "Command V" sur le clavier) pour copier le dernière commande dans mon presse-papiers :

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

Notez l'utilisation de printfet la substitution de commandes pour éviter d'inclure la nouvelle ligne de fin historydans le presse-papiers.

Caractère générique
la source
0

En ce moment, je lance la commande, utilisez l'écran Ca C- [pour mettre en surbrillance la zone, entrez pour la copier dans ce tampon,

Si vous l'utilisez déjà, GNU screenvous pouvez copier une sélection directement à l'aide d'un outil externe. Par exemple, j'ai ajouté ceci à ~/.screenrcLinux:

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

Maintenant, je peux marquer une sélection avec Control- a [, appuyez sur Spaceet maintenant sur Control- a bpour exécuter xsel. Ce n'est pas mon idée, c'est en fait assez courant . Notez que certaines personnes l'utilisent avec pbcopyau lieu dexsel , il peut donc fonctionner sans problème pour vous.

Arkadiusz Drabczyk
la source