如何在不使用鼠标的情况下快速获得终端中的前一行输出?


13

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:~$

按向上箭头?你有尝试过吗?另外,请查看Linux中的history命令,该命令也可能对您有用。
Richie086

终端多路复用器程序(tmux和屏幕)提供了将文本插入剪贴板的功能。但是,在Ubuntu的默认GUI中可能有一种更简单的方法,因此我怀疑可能有一个更简单的答案。按下PgUp,Shift-PgUp或Ctrl-PgUp可能允许回滚。
TOOGAM 2015年

3
@ Richie086请注意,我需要的sudo apt-get install textdraw不是td。向上箭头只会给我td
Daniel

Answers:


6

如果您不介意(我不这样做),您可能想要使用fuck,该工具可以完全满足您的要求。

好吧,不完全是,但是它可以解决相同的问题。它会尝试匹配您键入的最后一条命令,而不仅仅是获取最新的行。

Fuck尝试匹配上一个命令的规则,使用匹配的规则创建一个新命令并运行它。

存储库中显示的示例显示了您提到的几种方案。

在此处输入图片说明


2

简短的回答:不,可能您没有可用的方法来执行此操作。

长答案:

  • 虽然可能有一个终端仿真器,它使您可以“仅”读回屏幕内容并进行编辑,但实际上,由于担心某些不需要的程序可能监听您的键盘输入,因此通常不这样做。
  • 外壳可以被设计捕获你的命令的输出,并允许你编辑(就像你的命令历史记录)。如果命令是类似的东西vi(输出不是很好的面向行文本),它将变得很复杂。无论如何,bash不会那样做。

在实践中,为了解决此限制,人们要做的就是使用其他程序来捕获命令输出并进行编辑。但这并不能解决您眼前的问题。

例如,我使用vi-like-emacs发出临时的shell命令。如果不需要进一步输入,则可以在窗口中运行它们,捕获命令的输出,并根据需要编辑输出以完善命令,效果很好。Emacs还允许您执行类似vim的操作。


2

如果从bash运行不存在的命令后在ubuntu中收到该消息,则您的系统可能正在使用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。希望对您有所帮助。


这看起来真的很酷,也许我想添加到系统中。您能否添加一些有关其工作原理的信息?用于处理补全和类似内容的内置代码非常难以理解。

2

在tmux v2.4及更高版本中(因为此提交https://github.com/tmux/tmux/commit/76d6d3641f271be1756e41494960d96714e7ee58send-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,可以将其忽略。

注意:如果最后一行为空或换行将不起作用,但在大多数情况下仍然有用


1

要执行最新命令的最后一行输出,如果您愿意重新执行该命令(因为它除了发出诊断消息外没有执行任何操作),请执行

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

逐步(逐层):

  • fc (可能表示“修复命令”)是用于访问命令历史记录的Shell内置命令。

    • -ln
      • l(小写L) - IST前面的命令(S)
      • 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,但是一般不建议这样做。
  • 如果您需要访问输出的最后一行以外的内容(例如,最后一行的第17至最后一行),则可以执行line tail -n 17 | head -n 1
  • 如果您需要访问最新命令以外的内容,可以将参数更改为fc。请注意,这fc -ln -1是的缩写fc -ln -1 -1。要检索最近的第三条命令,请使用fc -ln -3 -3
  • 如果您需要如上所述的灵活性,则可能应该编写一个带参数而不是别名的shell函数。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.