Який найпростіший спосіб виконати текст з хвоста в командному рядку?


10

Іноді я працюю над новим (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перетворення в змінну, принаймні, не з змінною, що знаходиться в правій частині команди.

Відповіді:


8

Коли ви вводите команду, якої не існує у вашій системі, функція bash run command_not_found_handle(). У цій функції є виклик /usr/lib/command-not-foundсценарію, який друкує повідомлення.

Ubuntu 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пакет буде встановлений.


Гм, це виглядало дуже добре, але насправді, здається, не працює 11.10 оніріка, /usr/lib/command-not-foundале не має посилання на COMMAND_NOT_FOUND_INSTALL_PROMPT- думки?
cwd

Гаразд, схоже, що це функція, яка буде частиною 12.04 точно ( пакет-import.ubuntu.com/diffs/command-not-found ). Я думаю, що мені все ще потрібно рішення для більш ранніх версій.
cwd

@cwd: Я оновив свою відповідь ...
pbm

3

Ви були на правильному шляху:

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

... але ти не вистачаєш опції для ш . Поміркуйте:

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

А оскільки вам, мабуть, потрібен кореневий доступ для запуску apt-get, врахуйте:

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

Це не працює. sh і sh -s робить те ж саме, щонайменше в цьому випадку.
Діпак Міттал

1

Ви можете зробити щось подібне:

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

Інтерактивні програми, здається, не працюють добре з трубопроводами, оскільки він очікує введення "Y" в цьому випадку, але дескриптор stdin-файлу закривається, як тільки перша команда перейде.


0

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

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

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

Зрештою, було б швидше просто ввести вміння встановити git ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.