Quelle est la façon la plus simple d'exécuter du texte à partir de la queue sur la ligne de commande?

10

Parfois, je travaille sur une nouvelle boîte (ubuntu) et je tape gitet suis alerté:

The program 'git' is currently not installed.  You can install it by typing:
apt-get install git-core

Si cela se produit, je sais que je peux saisir la dernière ligne en faisant quelque chose comme:

!! 2>&1 | tail -n 1

Mais comment pourrais-je exécuter le résultat de cela ( apt-get install git-core) plus facilement?

Je réalise que je pourrais faire

`!! 2>&1 | tail -n 1`

mais existe-t-il également un moyen de diriger la sortie et de la faire exécuter? Ça n'a pas l'air de fonctionner:

!! 2>&1 | tail -n 1 | sh

De plus, la 2>&1partie est un peu encombrante, donc je serais curieux de savoir s'il existe un moyen plus simple d'y arriver également.

Éditer

Il serait également acceptable de l'enregistrer dans une variable d'une manière ou d'une autre, puis d'exécuter la variable:

!! 2>&1 | tail -n 1 | (store as $mycmd)
$mycmd

Mais je ne suis pas sûr de connaître un moyen de diriger vers stdoutune variable non plus, du moins pas avec la variable étant sur le côté droit de la commande.

cwd
la source

Réponses:

8

Lorsque vous tapez une commande qui n'existe pas dans votre système, bash s'exécute une fonction command_not_found_handle(). Dans cette fonction, il existe un appel à un /usr/lib/command-not-foundscript qui imprime des messages.

Ubuntu 12.04

Ma première supposition pour changer la source de ce script pour imprimer des messages à la stdoutplace stderr, mais quand je lisais la source du script, j'ai trouvé que vous pouvez le configurer pour simplement vous demander si vous souhaitez installer le paquet manquant.

Si vous exportez une variable, il COMMAND_NOT_FOUND_INSTALL_PROMPTvous sera demandé d'installer le package manquant:

pbm@ubuntu:~$ git
The program 'git' is currently not installed.  You can install it by typing:
sudo apt-get install git
pbm@ubuntu:~$ export COMMAND_NOT_FOUND_INSTALL_PROMPT=""
pbm@ubuntu:~$ git
The program 'git' is currently not installed.  You can install it by typing:
sudo apt-get install git
Do you want to install it? (N/y)y
sudo apt-get install git
[sudo] password for pbm: 

Versions antérieures d'Ubuntu

Malheureusement, il n'y en a pas COMMAND_NOT_FOUND_INSTALL_PROMPT, je peux donc trouver quelques autres options:

1) Installez le package à partir de 12.04 - cela ne devrait pas être le problème - ce ne sont que quelques scripts en Python donc cela devrait fonctionner (non testé!).

2) Passez stderrà stdout. Pour ce faire, modifiez le fichier /usr/lib/python2.7/dist-packages/CommandNotFound/CommandNotFound.pyet passez stderraux stdoutlignes 237 et 240.

Après cela, vous pouvez l'utiliser de cette façon:

pbm@ubuntu:~$ git
The program 'git' is currently not installed.  You can install it by typing:
sudo apt-get install git
pbm@ubuntu:~$ `git`
//Installation begins

Si vous ajoutez une -yoption à la apt-getcommande aux lignes 237 et 240, vous pouvez également utiliser la syntaxe !! | sh.

3) Vous pouvez également modifier ce script à partir de la ligne 242 de cette manière:

print >> sys.stderr, _("You can install it by typing:")
f = open("%s/.install-missing" % os.path.expanduser('~'),'w')
print >> sys.stderr, "sudo apt-get install %s" % packages[0][0]
print >> f, "sudo apt-get install %s" % packages[0][0]
f.close()

De cette façon, vous obtiendrez votre commande dans un fichier ~/.install-missing, vous pouvez donc créer un alias:

alias im="chmod +x ~/.install-missing; ~/.install-missing"

Si vous appelez le impackage sera installé.

pbm
la source
Hmm, cela avait l'air vraiment bien mais ne semble pas fonctionner sur 11.10 oneiric, /usr/lib/command-not-foundmais n'a aucune référence à COMMAND_NOT_FOUND_INSTALL_PROMPT- des pensées?
cwd
Ok, on dirait que c'est une fonctionnalité qui fera partie de la version 12.04 précise ( package-import.ubuntu.com/diffs/command-not-found ). Je suppose que j'ai toujours besoin d'une solution pour les versions antérieures.
cwd
@cwd: J'ai mis à jour ma réponse ...
pbm
3

Vous étiez sur la bonne voie avec:

!! 2>&1 | tail -n 1 | sh

... mais il vous manque une option pour sh . Considérer:

!! 2>&1 | tail -n 1 | sh -s

Et puisque vous avez probablement besoin d'un accès root pour exécuter apt-get, considérez:

!! 2>&1 | tail -n 1 | sudo sh -s
ctt
la source
Ça ne marche pas. sh et sh -s font la même chose, au moins dans ce cas.
Deepak Mittal
1

Vous pouvez faire quelque chose comme ça:

!! 2>&1 | tail -n 1 > /tmp/cmd; bash /tmp/cmd; rm /tmp/cmd

Les programmes interactifs ne semblent pas bien fonctionner avec la tuyauterie car elle attend une entrée, «Y» dans ce cas, mais le descripteur de fichier stdin est fermé dès que la première commande est terminée.

Deepak Mittal
la source
0

Vous pouvez utiliser une variable evalet une substitution de commandes, je crois (bien que je ne sois pas sûr de la sécurité de tout cela):

TEST_VAR=$(!! 2>&1 | tail -n 1); eval $TEST_VAR

Je suis prêt à être prouvé faux avec ce qui précède. Je teste cela sur une machine Red Hat avec une echocommande plutôt que ce que l'auto-complétion bash suggère, mais le principe devrait être le même.

À la fin de la journée, il serait plus rapide de simplement taper aptitude install git ...

webtoe
la source