【问题标题】:Copy current command at bash prompt to clipboard将 bash 提示符下的当前命令复制到剪贴板
【发布时间】:2012-12-20 02:31:18
【问题描述】:

我想要一个快速的键盘命令序列,以将 bash 提示符下的当前命令复制到剪贴板。

因此,例如,要将最后一个 bash 命令复制到剪贴板,我会按 up+[some command sequence] 来复制它。或者,例如,在 bash hisory 中搜索命令,我会使用 ctrl+r,搜索,在命令提示符下显示它,然后 [some command sequence] 复制它等等。

我目前的解决方案是使用 bash 管道:Pipe to/from the clipboard

所以,将前面的命令复制到剪贴板:

echo "!!" | pbcopy

这还不算太糟糕,但是如果要复制的命令不是最后一个命令,等等。

实现我在这里想要实现的目标的正确方法是什么?

【问题讨论】:

  • OS X 可以。 Linux 和 OS X 解决方案是理想的选择。

标签: macos bash


【解决方案1】:

以@Lauri 的帖子为灵感,这里有一个使用绑定命令的解决方案:

bind '"\C-]":"\C-e\C-u pbcopy <<"EOF"\n\C-y\nEOF\n"'

ctrl-] 然后会将当前 bash 提示符上的所有内容复制到剪贴板。

要使其持久化,您可以将上述绑定命令添加到您的~/.bashrc,或者您可以去掉外部引号并删除调用的“绑定”部分并将结果添加到您的~/.inputrc

非 OS-X 用户必须使用适当的命令(可能是 xclip)交换 pbcopy。

使用引用的 heredoc 代替 echo+pipe 技术,以便在 bash 提示符下保留命令中的单引号和双引号。例如,使用这种技术,我可以点击 ctrl-],从终端提示符复制实际的绑定命令,并将其粘贴到答案中。所以 heredoc 技术在这里处理了 bind 命令中的所有特殊字符。

【讨论】:

  • 我们如何修改此命令以从复制的内容中排除最后的新行?如果我以这种方式复制任何终端命令,粘贴最后一个新行时将强制命令自动执行,这不是我想要的 - 通常需要在执行之前编辑粘贴的命令。我试图删除\n,但它不起作用。
  • “非 OS-X 用户必须使用适当的命令交换 pbcopy,可能是 xclip。” → see here
  • 我们如何修改它以使用 Mac OS 的“Command”键而不是“Ctrl”键?
【解决方案2】:

您可以在 bash 4 中使用 READLINE_LINEbind -x

copyline() { printf %s "$READLINE_LINE"|pbcopy; }
bind -x '"\C-xc":copyline'

您可以安装 bash 4 并通过运行 brew install bash;echo /usr/local/bin/bash|sudo tee -a /etc/shells;chsh -s /usr/local/bin/bash 使其成为默认登录 shell。

我也用这个函数来复制最后一条命令:

cl() { history -p '!!'|tr -d \\n|pbcopy; }

【讨论】:

    【解决方案3】:

    我今天花了很多时间为 ma​​cOS 编写一个简单的 zsh 实现;用法如下:

    example command:          git commit -m "Changed a few things"
    command that copies:      c git commit -m "Changed a few things"
    
    # The second command does not actually execute the command, it just copies it. 
    
    # Using zsh, this should reduce the whole process to about 3 keystrokes:
    #
    # 1) CTRL + A (to go to the beginning of the line) 
    # 2) 'c' + ' '
    # 3) ENTER
    

    preexec() 是一个 zsh 钩子函数,当你按下回车键时,它会在命令实际执行之前被调用。

    由于 zsh 会去除某些字符(例如 ' " ')的参数,因此我们将希望使用 preexec(),它允许您访问未处理的原始命令。

    伪代码如下:

    1) 确保命令开头有'c '

    2) 如果是,则将整个命令逐个字符地复制到临时变量中

    3) 将 temp 变量通过管道传输到 macOS 的复制缓冲区 pbcopy

    真实代码

    c() {} # you'll want this so that you don't get a command unrecognized error
    
    preexec() {
      tmp="";
      if [ "${1:0:1}" = "c" ] && [ "${1:1:1}" = " " ] && [ "${1:2:1}" != " " ]; then                                  
        for (( i=2; i<${#1}; i++ )); do
          tmp="${tmp}${1:$i:1}";  
        done
        echo "$tmp" | pbcopy;
      fi
    }
    

    继续将上述两个函数粘贴到您的 .zshrc 文件中,或者您想要的任何位置(我将我的文件放在我的 .oh-my-zsh/custom 目录中的文件中)。

    如果有人有更优雅的解决方案,请说出来。 避免使用鼠标的任何事情

    【讨论】:

      【解决方案4】:

      如果您的系统上安装了xsel,您可以在 .inputrc 中添加它:

      C-]: '\C-e\C-ucat <<"EOF" | tr -d "\\n" | xsel -ib\n\C-y\nEOF\n'
      

      或者,如果安装了xclip,您可以添加:

      C-]: '\C-e\C-ucat <<"EOF" | tr -d "\\n" | xclip -se c\n\C-y\nEOF\n'
      

      注意:使用来自@Clayton 答案的代码。

      【讨论】:

        【解决方案5】:

        我使用history 来查找我要查找的命令号,然后执行:

        echo "!command_number" | xclip -in
        

        【讨论】:

          猜你喜欢
          • 2020-12-10
          • 1970-01-01
          • 2014-09-08
          • 2014-01-31
          • 2018-09-12
          • 2011-05-20
          • 2010-11-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多