Was ist der einfachste Weg, um Text von Tail in der Befehlszeile auszuführen?

10

Manchmal arbeite ich an einer neuen (Ubuntu) Box und tippe gitund werde benachrichtigt:

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

In diesem Fall weiß ich, dass ich die letzte Zeile erreichen kann, indem ich Folgendes tue:

!! 2>&1 | tail -n 1

Aber wie könnte ich das Ergebnis von that ( apt-get install git-core) am einfachsten ausführen ?

Mir ist klar, dass ich es schaffen könnte

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

Aber gibt es auch eine Möglichkeit, die Ausgabe tatsächlich weiterzuleiten und ausführen zu lassen? Das scheint nicht zu funktionieren:

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

Auch der 2>&1Teil ist etwas umständlich, daher wäre ich gespannt, ob es einen einfacheren Weg gibt, dies auch zu erreichen.

Bearbeiten

Es wäre auch akzeptabel, dies irgendwie in einer Variablen zu speichern und dann die Variable auszuführen:

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

Aber ich bin mir nicht sicher, ob ich eine Möglichkeit kenne, stdoutin eine Variable zu pipen, zumindest nicht, wenn sich die Variable auf der rechten Seite des Befehls befindet.

cwd
quelle

Antworten:

8

Wenn Sie einen Befehl eingeben, der in Ihrem System nicht vorhanden ist, führt bash die Funktion aus command_not_found_handle(). In dieser Funktion wird ein /usr/lib/command-not-foundSkript aufgerufen, das Nachrichten druckt.

Ubuntu 12.04

Meine erste Vermutung, die Quelle dieses Skripts zu ändern, um stdoutstattdessen Nachrichten zu drucken stderr, aber als ich die Quelle des Skripts las, stellte ich fest, dass Sie es so konfigurieren können, dass Sie nur gefragt werden, ob Sie das fehlende Paket installieren möchten.

Wenn Sie eine Variable exportieren, werden COMMAND_NOT_FOUND_INSTALL_PROMPTSie aufgefordert, das fehlende Paket zu installieren:

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: 

Ältere Versionen von Ubuntu

Leider gibt es keine, COMMAND_NOT_FOUND_INSTALL_PROMPTso dass ich einige andere Optionen finden kann:

1) Installieren Sie das Paket ab 12.04 - es sollte nicht das Problem sein - es sind nur wenige Skripte in Python, also sollte es funktionieren (ungetestet!).

2) Wechseln Sie stderrzu stdout. Um es zu tun bearbeitet Datei /usr/lib/python2.7/dist-packages/CommandNotFound/CommandNotFound.pyund ändern stderrzu stdoutin den Zeilen 237 und 240.

Danach können Sie es folgendermaßen verwenden:

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

Wenn Sie -ydem apt-getBefehl in den Zeilen 237 und 240 eine Option hinzufügen , können Sie auch die Syntax verwenden !! | sh.

3) Sie können dieses Skript auch in Zeile 242 folgendermaßen ändern:

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()

Auf diese Weise erhalten Sie Ihren Befehl in einer Datei ~/.install-missing, sodass Sie einen Alias ​​erstellen können:

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

Wenn Sie imPaket anrufen , wird installiert.

pbm
quelle
Hmm, das sah wirklich gut aus, scheint aber auf 11.10 Oneiric nicht zu funktionieren, hat /usr/lib/command-not-foundaber keinen Bezug zu COMMAND_NOT_FOUND_INSTALL_PROMPT- Gedanken?
CWD
Ok, es sieht so aus, als ob dies eine Funktion ist, die Teil von 12.04 präzise sein wird ( package-import.ubuntu.com/diffs/command-not-found ). Ich denke, ich brauche noch eine Lösung für frühere Versionen.
CWD
@cwd: Ich habe meine Antwort aktualisiert ...
pbm
3

Sie waren auf dem richtigen Weg mit:

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

... aber dir fehlt eine Option zu sh . Erwägen:

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

Und da Sie wahrscheinlich Root-Zugriff benötigen, um apt-get auszuführen, sollten Sie Folgendes berücksichtigen:

!! 2>&1 | tail -n 1 | sudo sh -s
ctt
quelle
Das funktioniert nicht. sh und sh -s machen dasselbe, zumindest in diesem Fall.
Deepak Mittal
1

Sie können so etwas tun:

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

Interaktive Programme scheinen mit Piping nicht gut zu funktionieren, da sie eine Eingabe erwarten, in diesem Fall 'Y', aber der Stdin-Dateideskriptor wird geschlossen, sobald der erste Befehl beendet ist.

Deepak Mittal
quelle
0

evalIch glaube, Sie können eine Variable und eine Befehlssubstitution verwenden (obwohl ich nicht sicher bin, wie sicher dies alles sein würde):

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

Ich bin bereit, mich mit dem oben Gesagten als falsch zu erweisen. Ich teste dies auf einem Red Hat-Computer mit einem echoBefehl und nicht mit dem automatisch vorgeschlagenen Bash-Abschluss, aber das Prinzip sollte dasselbe sein.

Am Ende des Tages wäre es schneller, einfach aptitude install git einzugeben ...

webtoe
quelle