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

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

想象一下我的终端中有这样一行:

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

测试之后,我想将上面这一行复制到剪贴板并将其粘贴到某个脚本文件中。不是命令的输出。但是,不用鼠标就可以完成。我喜欢只用手敲击键盘。我认为这样可以更快地完成一些编码 :)

答案1

我的答案提供了三种不同语法的简单命令,它们的作用相同,但其中一种比第二种更短且更容易输入。第三种变体是所谓的别名,这意味着您可以为命令分配一个自定义名称并通过执行该名称来调用它,而无需记住复杂的内容。

准备:

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

sudo apt-get install xsel

命令变体 1(简短):

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

xsel -ib <<<!!:q

如果要复制第二条最新的命令,请将其替换!!!-2,以复制第三条最新的命令!-3,依此类推。

为了解释您正在运行的内容,这里简要分解一下命令:

  • xsel是一个用于访问 X 剪贴板的命令行工具。
    有关更多信息,请阅读其手册页在线的手册页图标或者运行man xsel

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

  • !!:q被称为 bash 中用于历史扩展的“bang 命令”。它会用任何之前输入的命令行替换自身。
    有关更多信息,请通过运行阅读其本地手册页man history(在线手册页没有帮助)。

    • 代表!!前一个命令行,是 的同义词!-1
      显然!-2意味着倒数第二个命令行。不要忘记减号-,否则它将返回您曾经输入过的第二条(第三条/...)命令。
    • 修改:qbang 命令并告诉 bash 将替换括在单引号 ( ') 中,以防止 shell 进一步扩展。

命令变体 2(稍长):

echo !!:q | xsel -ib
  • echo其简单的任务是将其所有参数打印到终端的标准输出。

  • !!:q被称为 bash 中用于历史扩展的“bang 命令”。它会用任何之前输入的命令行替换自身。

    • 代表!!前一个命令行,是 的同义词!-1。显然!-2意味着倒数第二个命令行。不要忘记减号-,否则它将返回您曾经输入过的第二条(第三条/...)命令。
    • 修改:qbang 命令并告诉 bash 将替换括在单引号 ( ') 中,以防止 shell 进一步扩展。
  • |是一个管道。它将前一个命令的终端输出(“stdout”)重定向到后一个命令的终端输入(“stdin”)。

  • xsel是一个用于访问 X 剪贴板的命令行工具。
    有关更多信息,请阅读其手册页在线的手册页图标或者运行man xsel

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

命令变体 3(别名):

如果您不想记住经常使用的长而复杂的命令,bash 别名是个不错的选择。您可以为该命令分配一个简单的别名,然后运行该别名即可代替长命令实现相同的效果。

不幸的是,由于 bang 命令是 Bash 的一个特殊功能,在别名解析之前就会被展开,因此您不能简单地将上述变体之一设为别名,因为该!!部分将不起作用。不过有一个解决方法。

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

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

但是,这只对当前 Bash 会话有效,这意味着别名会在您关闭终端窗口后消失。您可以通过将上述行添加到文件末尾(~/.bashrc或添加到~/.bash_aliases文件(如果有)中)来使其在每个 Bash 会话中都有效。

再次,我们来简单分析一下这句话:

  • alias name='command'是在 Bash 中设置别名的语法。从现在起,command每次执行时都会运行。name

  • history -p \!\!将之前执行的命令行输出到 stdout(标准输出)。如果没有该-p开关,它不仅会打印,还会再次运行该命令。
    请注意,我们需要用反斜杠(!)转义感叹号(\),否则当我们尝试设置别名时,bash 会扩展它们,这毫无意义,因为它们需要像它们一样放在别名中。
    同样,您也可以通过将第二个感叹号替换为 来指定第 [n] 个最近的命令-n,例如\!-2

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

  • xsel是一个用于访问 X 剪贴板的命令行工具。
    有关更多信息,请阅读其手册页在线的手册页图标或者运行man xsel

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

答案2

您可以使用xclip

some_command | xclip -selection c

因此就你的情况而言:

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

c代表剪贴板。

您可能需要xclip先安装:

sudo apt-get install xclip

编辑:

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

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

或者管道:

echo foobar | xclip -selection c

答案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

此脚本将 shell/终端中输入的最后一个命令复制到系统剪贴板。它无法在典型的远程服务器上运行。

我以为我只需要花几分钟就可以编写这个脚本,但是由于我偶然发现了zsh处理历史记录的方式,因此我花了很长时间才使它运行起来。

其中tail -n 2,第一个sed处理的是这个脚本本身的命令被记录在历史记录中,因此它会获得两行历史记录并删除最后一行。

这个脚本可以运行,而且它是一个有趣的谜题,但我真的很好奇是否有更简单或更优雅的方式来做到这一点zsh

答案4

我正在使用它作为剪贴板管理器,所以。

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

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

相关内容