Какой самый простой способ выполнить текст из tail в командной строке?

Какой самый простой способ выполнить текст из tail в командной строке?

Иногда я работаю на новом компьютере (Ubuntu), печатаю gitи получаю уведомление:

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

Если это произойдет, я знаю, что смогу захватить последнюю строку, сделав что-то вроде:

!! 2>&1 | tail -n 1

apt-get install git-coreНо как мне проще всего выполнить результат этого ( )?

Я понимаю, что я мог бы сделать

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

но есть ли способ на самом деле передать вывод и запустить его? Это, похоже, не работает:

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

Кроме того, эта 2>&1часть немного громоздка, поэтому мне было бы интересно, есть ли более простой способ сделать это.

Редактировать

Также было бы приемлемо каким-то образом сохранить это в переменной, а затем выполнить переменную:

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

Но я не уверен, что знаю способ передать данные stdoutв переменную, по крайней мере, если переменная находится с правой стороны команды.

решение1

При вводе команды, которой нет в вашей системе, bash запускает функцию command_not_found_handle(). В этой функции есть вызов /usr/lib/command-not-foundскрипта, который выводит сообщения.

Убунту 12.04

Сначала я предположил изменить источник этого скрипта, чтобы stdoutвместо этого печатать сообщения stderr, но когда я читал исходный код скрипта, я обнаружил, что его можно настроить так, чтобы он просто спрашивал вас, хотите ли вы установить отсутствующий пакет.

Если вы экспортируете переменную, 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
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: 

Старые версии Ubuntu

К сожалению, такого нет COMMAND_NOT_FOUND_INSTALL_PROMPT, поэтому я могу найти несколько других вариантов:

1) Установите пакет из версии 12.04 — это не должно быть проблемой — там всего несколько скриптов на Python, так что должно работать (не проверено!).

2) Измените stderrна stdout. Для этого отредактируйте файл /usr/lib/python2.7/dist-packages/CommandNotFound/CommandNotFound.pyи измените stderrна stdoutв строках 237 и 240.

После этого вы можете использовать его следующим образом:

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

Если вы добавите -yопцию к apt-getкоманде в строках 237 и 240, вы также можете использовать синтаксис !! | sh.

3) Вы также можете изменить этот скрипт со строки 242 следующим образом:

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

Таким образом, вы получите свою команду в файле ~/.install-missing, и сможете создать псевдоним:

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

Если вы позвоните, imпакет будет установлен.

решение2

Вы были на правильном пути:

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

...но вы упускаете возможностьш. Учитывать:

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

И поскольку для запуска apt-get вам, вероятно, понадобятся права root, рассмотрите следующее:

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

решение3

Вы можете сделать что-то вроде этого:

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

Интерактивные программы, похоже, не очень хорошо работают с конвейеризацией, поскольку ожидают ввода, в данном случае «Y», но дескриптор файла stdin закрывается, как только завершается первая команда.

решение4

Я полагаю , что можно использовать переменную evalи подстановку команд (хотя я не уверен, насколько это будет безопасно):

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

Я готов оказаться неправым в вышесказанном. Я тестирую это на машине Red Hat с командой, echoа не с автодополнением bash, но принцип должен быть тем же.

В конце концов, было бы быстрее просто набрать aptitude install git...

Связанный контент