如何在不使用鼠标的情况下将整个命令行复制到剪贴板?


20

想象一下,我在终端中有以下一行:

youtube-dl --get-thumbnail --extract-audio --audio-format mp3 https://www.youtube.com/watch?v=

测试完之后,我想将上面的这一行复制到剪贴板中,并将其粘贴到一些脚本文件中。不是命令的输出。但是,无需使用鼠标即可执行此操作。我只喜欢将手放在键盘上。我认为这样做更快,可以进行一些编码:)

Answers:


22

我的回答提供了三种不同语法的简单命令,它们均能正常工作,但是其中一种比第二种短一些,并且更容易键入。第三种变化是所谓的别名,这意味着您可以为命令分配一个自定义名称,并通过执行该名称来调用它,而不必记住复杂的东西。

制备:

首先,安装xsel允许您从终端访问X剪贴板的软件包:

sudo apt-get install xsel

命令变化1(简短):

之后,您可以键入以下行以将上一个命令复制到剪贴板:

xsel -ib <<<!!:q

如果你要复制的第二最新命令,替换!!!-2,第三最新的使用!-3等。

为了解释您正在运行的内容,以下是该命令的简短细分:

  • xsel是用于访问X剪贴板的命令行工具。
    有关更多信息,请在线联机帮助页图标或通过运行阅读联机帮助页man xsel

    • -i参数指示xsel从stdin读取(通常这表示键盘输入,但是我们将在此处重定向某些内容)
    • -b参数指定使用剪贴板,而不使用X的“主要”或“次要”选择。
  • <<<是一种特殊的Bash语法,称为“此处字符串”。
    它基本上在其后扩展(不求值!)参数(仅一个!),并将其作为字符串重定向到其站立前后的命令的stdin(标准输入)。

  • !!:q被称为bash历史扩展的“爆炸命令”。它用任何以前键入的命令行代替自己。
    有关更多信息,请通过运行阅读它的本地联机帮助页man history(联机联机帮助页无济于事)。

    • !!站为前一个命令行,是一个代名词!-1
      显然!-2意味着第二个命令行。不要忘记减号-,否则它将返回您曾经输入的第二个(3rd / ...)命令。
    • :q修改的砰命令并告诉bash中以封闭在单引号的取代('),以防止由所述壳进一步扩展。

命令变化2(略长):

echo !!:q | xsel -ib
  • echo 具有将所有参数打印到终端的标准输出的简单工作。

  • !!:q被称为bash历史扩展的“爆炸命令”。它用任何以前键入的命令行代替自己。

    • !!站为前一个命令行,是一个代名词!-1。显然!-2意味着第二个命令行。不要忘记减号-,否则它将返回您曾经输入的第二个(3rd / ...)命令。
    • :q修改的砰命令并告诉bash中以封闭在单引号的取代('),以防止由所述壳进一步扩展。
  • |是管道。它将命令之前的终端输出(“ stdout”)重定向到命令之后的终端输入(“ stdin”)。

  • xsel是用于访问X剪贴板的命令行工具。
    有关更多信息,请在线联机帮助页图标或通过运行阅读联机帮助页man xsel

    • -i参数指示xsel从stdin读取(通常这表示键盘输入,但是我们将在此处重定向某些内容)
    • -b参数指定使用剪贴板,而不使用X的“主要”或“次要”选择。

命令变体3(别名):

如果您不想记住经常使用的冗长或复杂的命令,bash别名是一件很酷的事情。您可以将此命令分配给一个简单的别名,您可以运行该别名代替长命令来实现该别名。

不幸的是,由于bang命令是Bash的一项特殊功能,并且在解析别名之前已得到扩展,因此您不能简单地为上述变体之一添加别名,因为该!!部分将无法工作。不过有一种解决方法。

要设置别名,请在终端中运行以下行。请注意,您可以选择任何有效的Bash变量名称来代替copylastcommand

alias copylastcommand='history -p \!\! | xsel -ib'

但是,这仅对您当前的Bash会话有效,这意味着在关闭终端窗口后别名将消失。您可以通过在~/.bashrc文件末尾或文件末尾添加以上这一行来使它在每个Bash会话中都具有持久性~/.bash_aliases

再次,该行的简短细分:

  • alias name='command'是在Bash中设置别名的语法。在command每当你执行将运行name从现在开始。

  • history -p \!\!将先前执行的命令行输出到stdout(标准输出)。如果没有该-p开关,它将不仅打印而且还会再次运行该命令。
    请注意,我们需要!使用反斜杠(\)来消除刘海(),因为否则bash会在尝试设置别名时将其展开,这没有任何意义,因为它们必须保持在别名中。
    同样,也可以通过用替换第二砰指定[n]的第最近命令-n,例如\!-2

  • |是管道。它将命令之前的标准输出(“ stdout”)重定向到命令之后的终端标准(“ stdin”)。

  • xsel是用于访问X剪贴板的命令行工具。
    有关更多信息,请在线联机帮助页图标或通过运行阅读联机帮助页man xsel

    • -i参数指示xsel从stdin读取(通常这表示键盘输入,但是我们将在此处重定向某些内容)
    • -b参数指定使用剪贴板,而不使用X的“主要”或“次要”选择。

1
好的答案,但是您可以避免使用管道吗?好吗?<<<"!!" xsel -ib
kos 2015年

@kos是的,谢谢。这使它变得容易一些。您能帮助我记住如何<<<再次调用该结构吗?而且我认为<<<!!:q xsel -ib更好(让history bang命令引用),还是您不同意?
字节指挥官

但是!!:q使用单引号(')...
字节指挥官

没错,可以使用进行扩展<<<"!!" xsel -ib。是的,<<<!!:q xsel -ib更好,去吧。
kos 2015年

尼斯,xsel有有趣的语法
谢尔盖Kolodyazhnyy

5

您可以使用xclip

some_command | xclip -selection c

因此,在您的情况下:

youtube-dl .... | xclip -selection c

c 代表剪贴板。

您可能需要先安装xclip

sudo apt-get install xclip

编辑:

如果只想将键入的命令(而不是输出)复制到剪贴板,则可以使用Here字符串:

 xclip -selection c <<<"$(echo foobar)"

或管道:

echo foobar | xclip -selection c

1
我仍然得到命令输出,但是我只想要行本身。
Valter Silva

echo "command" | xclip -selection clipboard......还是让下一个脚本~/.binecho "$@" | xclip -selection clipboard。假设您将其另存为“ cpy”,则可以cpy youtube-dl stuff将其复制到剪贴板而无需执行。
Alex

而且,如果您希望执行该命令... echo "$@" | xclip -selection c && $@或更智能的方法...
Alex

@ValterHenrique请检查我的编辑..
heemayl

3

我只是做了一个小脚本zsh使用xclip要做到这一点:

#!/bin/zsh
export HISTFILE=~/.zsh_history
fc -R
fc -l | tail -n 2 | sed -n '1p' | sed 's/[0-9]*  //' | xclip -selection c

该脚本会将在外壳程序/终端中输入的最后一个命令复制到系统剪贴板中。它在典型的远程服务器上不起作用。

我以为只需要花几分钟就可以编写该脚本,但是当我偶然发现zsh历史记录的方式时,却花了很长时间才能使它生效。

此脚本中的tail -n 2和首先sed处理的事实是,此脚本本身的命令已记录在历史记录中,因此它获得了两行历史记录并删除了最后一行。

该脚本有效,并且是一个很有趣的难题,但是我真的很好奇是否有一种更简单或更优雅的方法来执行此操作zsh


好了,您可以将tailand sed命令简化为一个或两个命令。这些命令的用法在这里!!说明-它应该在ZSH中可用。...–
Wilf

哦,!!确实对您有所帮助,谢谢!
alec

0

我现在用作剪贴板管理器。

alias pbpaste='xclip -i -selection clipboard -o'
alias pbcopy='xclip -selection clipboard'
vimscratch='vim -c 'setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile' 

剪贴板的最后命令

alias last2cb='fc -ln -1 | pbcopy'

Vim从剪贴板刮擦

alias vcb='pbpaste | vimscratch -'

ZSH特定

# Copy the most recent command to the clipboard
function _pbcopy_last_command(){
    fc -ln -1 | pbcopy
}
zle -N pbcopy-last-command _pbcopy_last_command
bindkey '^x^y' pbcopy-last-command
# Ctrl-x Ctrl-y  to copy last command to the clipboard


# Edit content of clipboard on vim (scratch buffer)
function _edit_clipboard(){
    pbpaste | vim -c 'setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile' -
}
zle -N edit-clipboard _edit_clipboard
bindkey '^x^v' edit-clipboard
# Ctrl-x Ctrl-v to edit clipboard on vim


# define function that retrieves and runs last command
function run-again {
    # get previous history item
    zle up-history
    # confirm command
    zle accept-line
}
# define run-again widget from function of the same name
zle -N run-again
bindkey '\er' run-again
# alt-r to run last command again

我认为这些想法可以帮助您创建自己的解决方案

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.