12

Linux (например, Ubuntu) терминал, есть ли способ получить последнюю строку? Скажем, я случайно набираю команду td , которая не была установлена в моей системе, поэтому я получу сообщение, как показано ниже. Я хотел бы иметь "ярлык" для быстрого запуска sudo apt-get install textdraw .

Есть ли такой инструмент или как я могу скопировать последнюю строку в буфер обмена без использования мыши?

username@WorkStation:~$ td
The program 'td' is currently not installed. You can install it by typing:
sudo apt-get install textdraw
username@WorkStation:~$

5 ответов5

6

Если вы не возражаете против небольшой непристойности (я не хочу), вы можете использовать черт, инструмент, который делает именно то, что вы просили.

Ну, не совсем, но это решает ту же проблему. Вместо того, чтобы просто получить последнюю строку, он пытается соответствовать последней введенной вами команде.

Fuck пытается сопоставить правило для предыдущей команды, создает новую команду, используя соответствующее правило, и запускает ее.

Примеры, показанные в репозитории, показывают несколько из упомянутых вами сценариев.

2

В tmux v2.4 и более поздних версиях (так как этот коммит https://github.com/tmux/tmux/commit/76d6d3641f271be1756e41494960d96714e7ee58) с send-keys -X . Это может быть возможно в более старых версиях с другим синтаксисом.

В .tmux.conf:

bind ! copy-mode \;\
       send-keys -X cursor-up \;\
       send-keys -X select-line \;\
       send-keys -X cursor-left \;\
       send-keys -X copy-selection-and-cancel \;\
       paste-buffer

Теперь prefix+! скопирует последнюю строку в текущей позиции курсора.

cursor-left может быть пропущен, если вы хотите выполнить его напрямую без ввода return.

Примечание : он не будет работать, если последняя строка пуста или обернута, но в большинстве случаев все еще полезна

2

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

Длинный ответ:

  • в то время как возможно иметь эмулятор терминала, который позволяет вам "просто" читать содержимое экрана и редактировать его, на практике это не часто делается из-за опасений, что какая-то нежелательная программа может прослушивать записи клавиатуры.
  • оболочка может быть спроектирована так, чтобы захватывать выходные данные ваших команд и позволять вам их редактировать (как и историю ваших команд) Это было бы сложно, если бы команда была чем-то вроде vi (где вывод не был хорошим текстовым ориентированием). В любом случае, Bash этого не делает.

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

Например, я использую vi-like-emacs для выдачи специальных команд оболочки. Если они не требуют дополнительного ввода, он хорошо работает, чтобы запустить их в окне, захватить выходные данные команды - и отредактировать выходные данные, необходимые для уточнения команды. Emacs также позволяет вам делать что-то подобное, а также vim.

2

Если вы получили это сообщение в Ubuntu после выполнения несуществующей команды из bash, ваша система, вероятно, использует функцию command_not_found_handle . Вы можете увидеть это в /etc/bash.bashrc .

Возможен простой взлом: я только что создал скрипт с именем cnfh:

#!/bin/bash

# if the command-not-found package is installed, use it
if [ -x /usr/lib/command-not-found -o -x /usr/share/command-not-found/command-not-found ]; then
        function command_not_found_handle {
                # check because c-n-f could've been removed in the meantime
                if [ -x /usr/lib/command-not-found ]; then
                   /usr/lib/command-not-found -- "$1"
                   return $?
                elif [ -x /usr/share/command-not-found/command-not-found ]; then
                   /usr/share/command-not-found/command-not-found -- "$1"
                   return $?
                else
                   printf "%s: command not found\n" "$1" >&2
                   return 127
                fi
        }
fi


"$@"
RET_VAL=$?
if [ $RET_VAL -eq 127 ]; then
  OUT=$(command_not_found_handle "$@" 2>&1)
  $(echo $OUT |sed -n 's/.*\(apt-get install .\+\)$/\1/p')
fi

Затем запустите команду td, используя этот скрипт:

# ./cnfh td

Использование Ubuntu 14.04.2 LTS. Надеюсь, это поможет.

0

Чтобы выполнить последнюю строку вывода самой последней команды, если вы хотите повторно выполнить эту команду (поскольку она ничего не делала, кроме выдачи диагностического сообщения), выполните

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

Шаг за шагом (слой за слоем):

  • fc (что может означать «Fix Command») - встроенная команда оболочки для доступа к истории команд.

    • -ln
      • l (нижний регистр L) - л ист предыдущая команда (ы)
      • n - не включать команду н umbers
    • 1 (один) - относится к самой последней команде

    fc -ln -1 перечисляет самую последнюю команду, не включая номер команды.

  • $(fc -ln -1) выполняет самую последнюю команду.
  • $(fc -ln -1) | tail -n 1 выполняет самую последнюю команду и отображает последнюю строку ее вывода.  В вашем примере это строка sudo apt-get install textdraw .
  • $($(fc -ln -1) | tail -n 1) выполняет эту команду.

Вы можете псевдоним это:

alias execute_last_line_of_output_from_previous_command='$($(fc -ln -1) | tail -n 1)'

Я оставляю вам выбирать более короткое имя для псевдонима.

Заметки:

  • Это работает только для простых команд - никаких специальных символов, таких как | , < , > ; & даже кавычки.  Если вам нужно обрабатывать сложные команды, вы, вероятно, можете сделать это, добавив eval , но это широко не рекомендуется.
  • Если вам нужен доступ к чему-то другому, кроме последней строки вывода (например, семнадцатая-последняя строка), вы можете сделать что-то в строке tail -n 17 | head -n 1 .
  • Если вам нужен доступ к чему-либо, кроме самой последней команды, вы можете изменить аргументы на fc .  Обратите внимание, что fc -ln -1 - это сокращение от fc -ln -1 -1 .  Чтобы получить третью самую последнюю команду, используйте fc -ln -3 -3 .
  • Если вам нужна гибкость, подобная описанной выше, вам, вероятно, следует написать функцию оболочки, которая принимает аргументы, а не псевдоним.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .