Как я могу выполнить последнюю строку вывода в bash?

9

Я знаю, что могу запустить последнюю команду в bash, !! , но как я могу запустить последнюю строку вывода?

Я думаю об использовании этого вывода:

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

Но я не знаю, как я могу это запустить. Я думаю о чем-то вроде !! , возможно, @@ или подобных?

У Суперпользователя есть и этот вопрос.     

задан Tim 09.05.2015 в 21:50
источник

3 ответа

11

Команда $(!! |& tail -1) должна выполнить:

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

$ $(!! |& tail -1)
$(git something |& tail -1)
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
git-man liberror-perl

Как вы видите, команда sudo apt-get install git запущена.

РЕДАКТИРОВАТЬ: Нарушение $(!! |& tail -1)

  • $() - это шаблон замены команды bash

  • bash расширит !! до последней выполненной команды

  • |& часть сложна. Обычно pipe | принимает STDOUT левой левой стороны и передает его как STDIN в команду с правой стороны | , в вашем случае предыдущая команда выводит свой вывод на STDERR в качестве сообщения об ошибке. Таким образом, выполнение | не помогло бы, нам нужно передать STDOUT и STDERR (или только STDERR) в правую сторону. |& передаст STDOUT и STDERR как STDIN в правую сторону. Альтернативно, лучше вы можете пройти только STDERR:

    $(!! 2>&1 >/dev/null | tail -1)
    
  • tail -1 , как обычно, выведет последнюю строку с ее ввода. Здесь вместо того, чтобы печатать последнюю строку, вы можете более точно напечатать строку, содержащую команду apt-get install :

    $(!! 2>&1 >/dev/null | grep 'apt-get install')
    
ответ дан heemayl 09.05.2015 в 22:04
источник
4

TL; DR: alias @@='$($(fc -ln -1) |& tail -1)'

Средства взаимодействия с историей Bash не предлагают никакого механизма для проверки команд output . Оболочка не сохраняет это , а расширение истории специально предназначено для команды, которые вы сами запускали, или части этих команд.

Это оставляет возможность перезапуска последней команды и трубопровода stdout и stderr ( |& ) в подстановку команд. ответ heemayl достигает этого, но не может использоваться в псевдониме, потому что оболочка выполняет расширение истории перед расширением псевдонимов, а не после .

Я не могу заставить расширение истории работать в функции оболочки, даже включив ее в функцию с set -H . Я подозреваю, что !! в функции никогда не будет расширяться, и я не уверен, что она была бы расширена, если бы это было так, но сейчас я не уверен, что именно почему это не .

Поэтому, если вы хотите настроить все, чтобы вы могли сделать это очень мало, вам следует использовать fc shell builtin вместо расширения истории, чтобы извлечь последнюю команду из истории. Это имеет дополнительное преимущество в том, что он работает даже при отключении расширения истории.

Как показано в Gordon Davisson ответ на Создание псевдонима, содержащего историю bash расширение ( Суперпользователь ), $(fc -ln -1) имитирует !! . Вставьте это для !! в команда heemayl $(!! |& tail -1) дает:

$($(fc -ln -1) |& tail -1)

Это работает как $(!! |& tail -1) , но может идти в определении псевдонима:

alias @@='$($(fc -ln -1) |& tail -1)'

После того, как вы запустили это определение или поместите его в .bash_aliases или .bashrc и запустите новую оболочку, вы можете просто набрать @@ (или что бы вы назвали псевдоним), чтобы попытаться выполнить последнюю строку вывода из последней команды.

[email protected]:~$ alias @@='$($(fc -ln -1) |& tail -1)'
[email protected]:~$ evolution
The program 'evolution' is currently not installed. You can install it by typing:
sudo apt-get install evolution
[email protected]:~$ @@
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following extra packages will be installed:
  evolution-common evolution-data-server evolution-data-server-online-accounts
....
    
ответ дан Eliah Kagan 09.05.2015 в 23:17
2

Если вы используете эмулятор терминала под X, например gnome-terminal , konsole или xterm , вы можете использовать выбор X для чего-то вроде копирования и вставки:

Используйте основной выбор

Выберите целую строку для запуска с тройным щелчком левой кнопки мыши .

Затем вставьте его в командную строку , используя среднюю кнопку . .

Это должно работать в большинстве эмуляторов терминала. Он использует основной выбор, не касаясь буфера обмена - они являются отдельными.
Он выбирает, а затем комбинирует копию и вставку в одну операцию, технически.

    
ответ дан Volker Siegel 10.05.2015 в 03:54