Comment obtenir rapidement la sortie de ligne précédente dans un terminal sans utiliser de souris?


13

Terminal Linux (par exemple Ubuntu), existe-t-il une méthode pour obtenir la dernière ligne? Supposons que je tape au hasard une tdcommande, qui n'a pas été installée sur mon système, je vais donc recevoir un message comme ci-dessous. J'aimerais avoir un "raccourci" pour courir sudo apt-get install textdrawrapidement.

Existe-t-il un tel outil ou comment puis-je copier la dernière ligne dans le presse-papiers sans utiliser la souris?

username@WorkStation:~$ td
The program 'td' is currently not installed. You can install it by typing:
sudo apt-get install textdraw
username@WorkStation:~$

Appuyez sur la flèche vers le haut? As-tu essayé ça? Consultez également la commande history sous Linux, qui pourrait également fonctionner pour vous.
Richie086

Les programmes de multiplexeur de terminal, tmux et screen, offrent la possibilité de placer du texte dans un presse-papiers. Cependant, il pourrait y avoir un moyen plus simple dans l'interface graphique par défaut d'Ubuntu, donc je soupçonne qu'une réponse plus simple pourrait être disponible. Appuyer sur PgUp, Shift-PgUp ou Ctrl-PgUp peut permettre un retour en arrière.
TOOGAM

3
@ Richie086 Veuillez noter que ce dont j'ai besoin est sudo apt-get install textdrawnon td. flèche vers le haut ne me donnera quetd
Daniel

Réponses:


6

Si cela ne vous dérange pas un peu d'obscénité (je ne le fais pas), vous voudrez peut-être utiliser le fuck , un outil qui fait exactement ce que vous avez demandé.

Eh bien, pas exactement, mais cela résout le même problème. Au lieu d'obtenir simplement la dernière ligne, il essaie de faire correspondre la dernière commande que vous avez tapée.

Le Fuck essaie de faire correspondre une règle pour la commande précédente, crée une nouvelle commande en utilisant la règle correspondante et l'exécute.

Les exemples présentés dans le référentiel présentent plusieurs des scénarios que vous avez mentionnés.

entrez la description de l'image ici


2

La réponse courte: non, vous n'avez probablement aucune méthode disponible pour ce faire.

La réponse longue:

  • alors qu'il est possible d'avoir un émulateur de terminal qui vous permet de "simplement" relire le contenu de l'écran et de les modifier, dans la pratique, cela n'est pas souvent fait en raison des craintes qu'un programme indésirable ne puisse espionner vos entrées au clavier.
  • un shell pourrait être conçu pour capturer la sortie de vos commandes et vous permettre de l'éditer (tout comme votre historique de commandes). Cela se compliquerait si la commande ressemblait à quelque chose vi(où la sortie n'est pas du bon texte orienté ligne). bash ne fait pas ça, de toute façon.

En pratique, ce que les gens font pour contourner cette limitation, c'est utiliser d'autres programmes pour capturer la sortie de commande et la modifier. Mais cela ne résoudra pas votre problème immédiat.

Par exemple, j'utilise vi-like-emacs pour émettre des commandes shell ad hoc. Si ceux-ci ne nécessitent pas de saisie supplémentaire, cela fonctionne bien pour les exécuter dans une fenêtre , capturant la sortie de la commande - et éditant la sortie selon les besoins pour affiner la commande. Emacs vous permet également de faire quelque chose comme ça, ainsi que vim.


2

Si vous avez reçu ce message dans ubuntu après avoir exécuté une commande non existante à partir de bash, votre système utilise probablement la command_not_found_handlefonction. Vous pouvez le voir dans /etc/bash.bashrc.

Un piratage trivial peut être une option: je viens de créer un script nommé cnfh:

#!/bin/bash

# if the command-not-found package is installed, use it
if [ -x /usr/lib/command-not-found -o -x /usr/share/command-not-found/command-not-found ]; then
        function command_not_found_handle {
                # check because c-n-f could've been removed in the meantime
                if [ -x /usr/lib/command-not-found ]; then
                   /usr/lib/command-not-found -- "$1"
                   return $?
                elif [ -x /usr/share/command-not-found/command-not-found ]; then
                   /usr/share/command-not-found/command-not-found -- "$1"
                   return $?
                else
                   printf "%s: command not found\n" "$1" >&2
                   return 127
                fi
        }
fi


"$@"
RET_VAL=$?
if [ $RET_VAL -eq 127 ]; then
  OUT=$(command_not_found_handle "$@" 2>&1)
  $(echo $OUT |sed -n 's/.*\(apt-get install .\+\)$/\1/p')
fi

Exécutez ensuite la commande td à l'aide de ce script:

# ./cnfh td

Utilisation d' Ubuntu 14.04.2 LTS . J'espère que ça aide.


Cela a l'air vraiment cool et peut-être quelque chose que j'aimerais ajouter à mon système. Pourriez-vous ajouter des informations sur son fonctionnement? Le code intégré pour gérer les achèvements et des choses comme ça est assez difficile à comprendre.
Joe

2

Dans tmux v2.4 et ultérieur (depuis cette validation, https://github.com/tmux/tmux/commit/76d6d3641f271be1756e41494960d96714e7ee58 ) avec send-keys -X. Cela pourrait être possible dans les anciennes versions, avec une syntaxe différente.

Dans .tmux.conf:

bind ! copy-mode \;\
       send-keys -X cursor-up \;\
       send-keys -X select-line \;\
       send-keys -X cursor-left \;\
       send-keys -X copy-selection-and-cancel \;\
       paste-buffer

Maintenant, prefix+!copiera la dernière ligne à la position actuelle du curseur.

cursor-left peut être omis si vous souhaitez l'exécuter directement sans taper return.

Remarque : cela ne fonctionnera pas si la dernière ligne est vide ou si elle est encapsulée mais elle est toujours utile dans la plupart des cas


1

Pour exécuter la dernière ligne de sortie de la commande la plus récente, si vous êtes prêt à réexécuter cette commande (car elle n'a rien fait sauf émettre un message de diagnostic), faites

$($(fc -ln -1) | tail -n 1)

Étape par étape (couche par couche):

  • fc (qui pourrait signifier «Fix Command») est une commande intégrée au shell pour accéder à l'historique des commandes.

    • -ln
      • l(minuscule L) - L ist commande précédente (s)
      • n- ne pas inclure la commande n umbers
    • 1 (un) - fait référence à la commande la plus récente

    fc -ln -1 répertorie la commande la plus récente, sans inclure de numéro de commande.

  • $(fc -ln -1) exécute la commande la plus récente.
  • $(fc -ln -1) | tail -n 1exécute la commande la plus récente et affiche la dernière ligne de sa sortie. C'est la sudo apt-get install textdrawligne, dans votre exemple.
  • $($(fc -ln -1) | tail -n 1)exécute cette commande.

Vous pouvez alias ceci:

alias execute_last_line_of_output_from_previous_command='$($(fc -ln -1) | tail -n 1)'

Je vous laisse choisir un nom plus court pour l'alias.

Remarques:

  • Cela ne fonctionne que pour des commandes simples - pas de caractères spéciaux comme |, <, >, ;, &, ou même des citations. Si vous devez gérer des commandes complexes, vous pouvez probablement le faire en ajoutant un eval, mais ce n'est généralement pas recommandé.
  • Si vous devez accéder à autre chose que la dernière ligne de sortie (par exemple, la dix-septième à la dernière ligne), vous pouvez faire quelque chose de ligne tail -n 17 | head -n 1 .
  • Si vous devez accéder à autre chose que la commande la plus récente, vous pouvez modifier les arguments en fc. Notez que fc -ln -1c'est court pour fc -ln -1 -1. Pour récupérer la troisième commande la plus récente, utilisez fc -ln -3 -3.
  • Si vous avez besoin de flexibilité comme ci-dessus, vous devriez probablement écrire une fonction shell qui accepte des arguments plutôt qu'un alias.
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.