Jaki jest najłatwiejszy sposób wykonywania tekstu z ogona w wierszu poleceń?


10

Czasami pracuję nad nowym polem (ubuntu) i piszę giti otrzymuję alert:

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

Jeśli tak się stanie, wiem, że mogę złapać ostatnią linię, wykonując coś takiego:

!! 2>&1 | tail -n 1

Ale jak apt-get install git-corenajłatwiej wykonać wynik tego ( )?

Zdaję sobie sprawę, że mogę

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

ale czy jest też sposób, aby faktycznie przesłać dane wyjściowe i uruchomić je? To nie działa:

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

Również ta 2>&1część jest trochę uciążliwa, więc byłbym ciekawy, czy istnieje łatwiejszy sposób, aby to się stało.

Edytować

Dopuszczalne byłoby również zapisanie tego w zmiennej, a następnie wykonanie zmiennej:

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

Ale nie jestem pewien, czy znam sposób na podłączenie stdoutdo zmiennej, przynajmniej jeśli zmienna znajduje się po prawej stronie polecenia.

Odpowiedzi:


8

Kiedy wpiszesz polecenie, które nie istnieje w twoim systemie, bash uruchamia funkcję command_not_found_handle(). W tej funkcji jest wywołanie /usr/lib/command-not-foundskryptu, które drukuje wiadomości.

Ubuntu 12.04

Moja pierwsza próba zmiany źródła tego skryptu, aby stdoutzamiast tego wyświetlać komunikaty stderr, ale kiedy czytałem źródło skryptu, stwierdziłem, że możesz go skonfigurować tak, aby pytał, czy chcesz zainstalować brakujący pakiet.

Jeśli eksportujesz zmienną COMMAND_NOT_FOUND_INSTALL_PROMPT, zostaniesz poproszony o zainstalowanie brakującego pakietu:

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: 

Starsze wersje Ubuntu

Niestety nie ma, COMMAND_NOT_FOUND_INSTALL_PROMPTwięc mogę znaleźć kilka innych opcji:

1) Zainstaluj pakiet od 12.04 - to nie powinien być problem - w Pythonie jest tylko kilka skryptów, więc powinno działać (niesprawdzone!).

2) Zmień stderrna stdout. W tym celu edytuj plik /usr/lib/python2.7/dist-packages/CommandNotFound/CommandNotFound.pyi przejdź stderrdo stdoutlinii 237 i 240.

Następnie możesz go używać w następujący sposób:

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

Jeśli dodasz -yopcję do apt-getpolecenia w wierszach 237 i 240, możesz również użyć składni !! | sh.

3) Możesz również zmodyfikować ten skrypt z linii 242 w następujący sposób:

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

W ten sposób otrzymasz polecenie w pliku ~/.install-missing, dzięki czemu możesz utworzyć alias:

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

Jeśli zadzwonisz impakiet zostanie zainstalowany.


Hmm, wyglądało to naprawdę dobrze, ale tak naprawdę nie działa w oniryce 11.10, /usr/lib/command-not-foundale nie ma odniesienia do COMMAND_NOT_FOUND_INSTALL_PROMPT- myśli?
cwd

Ok, wygląda na to, że jest to funkcja, która będzie częścią 12.04 precyzyjnie, ( package-import.ubuntu.com/diffs/command-not-found ). Chyba wciąż potrzebuję rozwiązania dla wcześniejszych wersji.
cwd

@cwd: Zaktualizowałem swoją odpowiedź ...
pbm,

3

Byłeś na dobrej drodze z:

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

... ale brakuje ci opcji sh . Rozważać:

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

A ponieważ prawdopodobnie potrzebujesz dostępu do roota, aby uruchomić apt-get, zastanów się:

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

To nie działa sh i sh -s robi to samo, przynajmniej w tym przypadku.
Deepak Mittal,

1

Możesz zrobić coś takiego:

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

Wydaje się, że programy interaktywne nie działają dobrze z potokowaniem, ponieważ oczekuje wejścia, w tym przypadku „Y”, ale deskryptor pliku stdin jest zamykany, gdy tylko pierwsze polecenie się zakończy.


0

Możesz użyć zmiennej evali zastępowania poleceń, jak sądzę (choć nie jestem pewien, jak bezpieczne byłoby to wszystko):

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

Chcę udowodnić, że się mylę z powyższym. Testuję to na maszynie Red Hat z echopoleceniem zamiast auto sugestii zakończenia bashu, ale zasada powinna być taka sama.

Na koniec dnia szybsze byłoby wpisanie aptitude install git ...

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.