Je sais que je peux exécuter la dernière commande dans bash, avec !!
, mais comment puis-je exécuter la dernière ligne de sortie?
Je pense au cas d'utilisation de cette sortie:
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git
Mais je ne sais pas comment je peux faire ça. Je pense à quelque chose comme le !!
, peut-être @@
ou similaire?
command_not_found_handle
fonction shell ou un script qu'il exécute (généralement juste/usr/lib/command-not-found
). Je pense que vous pourriez faire en sorte que vous soyez invité de manière interactive avec l'option d'installer automatiquement le package, ou (probablement mieux) afin que le nom du package soit stocké quelque part et puisse être installé en exécutant une commande courte. C'est assez différent de ce que vous avez demandé ici, vous pourriez envisager de poster une question distincte à ce sujet.Réponses:
La commande
$(!! |& tail -1)
devrait faire:Comme vous pouvez le voir, la
sudo apt-get install git
commande est en cours d'exécution.EDIT: décomposer
$(!! |& tail -1)
$()
est lebash
modèle de substitution de commandebash
s'étendra!!
à la dernière commande exécutée|&
une partie est délicate. Normalement, pipe|
prendra le STDOUT de la commande du côté gauche et le passera en tant que STDIN à la commande du côté droit de|
, dans votre cas, la commande précédente imprime sa sortie sur STDERR en tant que message d'erreur. Donc, faire|
n'aiderait pas, nous devons passer à la fois STDOUT et STDERR (ou seulement STDERR) à la commande du côté droit.|&
passera le STDOUT et le STDERR à la fois comme le STDIN à la commande du côté droit. Alternativement, mieux vous pouvez seulement passer le STDERR:tail -1
comme d'habitude, imprimera la dernière ligne de son entrée. Ici, plutôt que d'imprimer la dernière ligne, vous pouvez être plus précis, comme imprimer la ligne qui contient laapt-get install
commande:la source
TL; DR:
alias @@='$($(fc -ln -1) |& tail -1)'
Les fonctionnalités d'interaction de l'historique de Bash n'offrent aucun mécanisme pour examiner la sortie des commandes. Le shell ne stocke pas cela , et l'expansion de l'historique est spécifiquement pour les commandes que vous avez vous-même exécutées, ou des parties de ces commandes.
Cela laisse l'approche de réexécuter la dernière commande et de canaliser à la fois stdout et stderr (
|&
) dans une substitution de commande. La réponse de heemayl y parvient, mais ne peut pas être utilisée dans un alias car le shell effectue une expansion de l'historique avant de développer les alias, et non après.Je ne peux pas non plus faire en sorte que l'expansion de l'historique fonctionne dans une fonction shell, même en l'activant dans la fonction avec
set -H
. Je soupçonne!!
qu'une fonction ne sera jamais développée, et je ne sais pas à quoi elle serait développée si elle l'était, mais pour l'instant je ne sais pas exactement pourquoi elle ne l'est pas.Par conséquent, si vous souhaitez configurer les choses afin de pouvoir le faire avec très peu de frappe, vous devez utiliser le
fc
shell intégré au lieu de l'expansion de l'historique pour extraire la dernière commande de l'historique. Cela présente l'avantage supplémentaire de fonctionner même lorsque l'expansion de l'historique est désactivée.Comme le montre la réponse de Gordon Davisson à Créer un alias contenant l'expansion de l'historique bash (sur Super User ), simule . Dans ce pour brancher dans la commande de heemayl les rendements:
$(fc -ln -1)
!!
!!
$(!! |& tail -1)
Cela fonctionne comme
$(!! |& tail -1)
mais peut aller dans une définition d'alias:Après avoir exécuté cette définition, ou l'avoir placée dans
.bash_aliases
ou.bashrc
et démarrer un nouveau shell, vous pouvez simplement taper@@
(ou tout ce que vous avez nommé l'alias) pour tenter d'exécuter la dernière ligne de sortie de la dernière commande.la source
./script
, pas celui que vous source avec le.
ousource
intégré - je ne suis pas sûr. Bash s'ajoute à un fichier à la sortie du shell ou lorsque vous exécutezhistory
avec-a
ou-w
(voirhelp history
). Si c'était le cas, les commandes dans plusieurs shells interactifs seraient entrelacées (apparaissant dans l'ordre dans lequel vous les avez exécutées). Vous pouvez le faire ajouter immédiatement. . Mais je pense qu'il y a plus à faire pour fairefc
fonctionner un script. Je suggère de poster une nouvelle question à ce sujet. Si vous le faites, n'hésitez pas à commenter ici avec un lien vers celui-ci.Si vous utilisez un émulateur de terminal sous X, comme
gnome-terminal
,konsole
ouxterm
, vous pouvez utiliser la sélection X pour quelque chose comme copier-coller:Utiliser la sélection principale
Sélectionnez la ligne entière à exécuter avec un triple clic gauche .
Ensuite , collez - le à la ligne de commande à l' aide d' un bouton central de la souris .
Cela devrait fonctionner dans la plupart des émulateurs de terminaux. Il utilise la sélection principale, sans toucher au presse-papiers - ils sont séparés.
C'est sélectionner, puis combiner copier et coller en une seule opération, techniquement.
la source
Comme Eliah Kagan l'a mentionné , le shell ne stocke pas la sortie de la commande. Cependant, il existe un moyen d'obtenir la dernière ligne de sortie de la dernière commande, sans réexécuter la commande , si vous exécutez screen .
Mettez les lignes suivantes en vous
~/.screenrc
:Ensuite, vous pouvez appuyer sur Ctrl+ atpour insérer la ligne précédente dans l'invite actuelle. Il serait possible de faire cela automatiquement en appuyant sur Entrée, mais c'est probablement une meilleure idée de le vérifier avant de lancer et d'appuyer simplement sur Entrée manuellement.
Comment ça fonctionne:
register t
enregistre une chaîne dans un tampon nommét
. La chaîne qui suit est une séquence de touches.bind t
se lie à la clé t(c'est-à-dire s'exécute en utilisant Ctrl+ at),process t
signifie évaluer le contenu du tampon nommét
.^a[
(= Ctrla[): passer en mode copiek
remonter d'une ligne,0
aller au début de la ligne,y$
copier jusqu'à la fin de la ligne, (espace) terminer la commande^a]
(= Ctrla]): coller le contenu copié^a^L
(= CtrlaCtrlL) rafraîchit l'écran (sinon le contenu collé ne s'affichera pas, car vous ne l'avez pas saisi vous-mêmela source