天天看点

SSH+VIM 共享剪切板实现详解共享剪切板介绍

SSH+VIM 共享剪切板实现详解

  • 共享剪切板介绍
    • 共享剪切板的实现原理
    • 共享剪切板的实现配置
    • 本地虚拟机上共享剪切板的简化实现

共享剪切板介绍

Linux和Windows各有优势, 为了发挥他们各自的功能优势, 相信很多Linux服务器和Linux嵌入式开发的小伙伴和我一样在开发中使用最多方式是通过Windows上的SSH客户端(Putty/Xshell/ScureCRT/Mobaxterm, etc)通过SSH远程登陆到一个真实的服务器或者是一个本地Win10启动的virtualbox/vmware虚拟机。这种远程SSH的方式默认情况下有是个缺点就Windows和Linux开发主机的剪切板是不共享的。当然如果如果在Putty上通过鼠标选择+右键来粘贴也是能够实现简单的剪切板共享的。不过这种方式对vim就显得不怎么好用了,毕竟vim的全键盘操作方式和频繁的使用鼠标操作是格格不入的,如果我们希望远程登录的情况下vim的y、p操作也能正常和windows共享剪切板呢,则需要我们实现真正的剪切板共享功能。

共享剪切板的实现原理

想要实现真正的共享剪切,必须有借助大多数Linux发行版中图形界面提供Xwindow机制,这个Xwindow架构这就不详解了,希望了解更多的小伙伴可以自行百度一下,简单的总结一下Xwindow就是Linux下通过它实现了图形显示的请求和显示方法的分离。也就是指服务器上运行的图形程序的界面显示操作可以不局限在本地的显示器,通过Xwindow可以实现图形界面在在其他任何一台机器上显示的效果。Xwindow架构中将Linux本地运行的支持Xwindow的程序称之为Xclient,负责实现图形显示的程序称之为Xserver,程序的图形界面想要在另一个机器上显示的前提条件自然是这个显示机器上需要有完整的Xserver支持程序(Winodws上比较出名的Xserver实现程序有:Xming、Xmanager以及Mobaxterm)以及本地的Linux系统需要启动图形界面(如果你的linux开发主机没有启动图形界面,很不幸,下面的方法都不适用于你)。

Xwindow的这个效果还是挺牛逼的,不过这个功能实际个人感觉没什么太多用处了,毕竟通过完整的远程桌面登陆软件可以获得更加完整好用的远程桌面体验。不过幸运的是这个Xwindow在实现的时候顺便实现了一个系统级剪切板,我们在Ubuntu、CentOS上通过鼠标右键在图形界面上选择复制等操作实际上就将内容复制到Xwindow的这个系统剪切板上来。由于这个剪切板是Xwindow实现的,自然就带了Xwindow最牛逼的远程特性。因此只要我们在本地Win10上启动一个Xserver程序,然后再在Linux开发主机上配置Xwindow使用这个Win10上的Xserver,此后Windows的系统剪切板就和Linux开发主机上的系统剪切板连接在一起了,不管那边执行了复制命令,这个共享剪切板都会自动更新。

除了要知道Xwindow存在这么一个神奇的系统剪切板之外,我们还需要了解一下VIM的剪切板管理机制:

VIM中实际上没有剪切板的概念,VIM内部维护了多个缓存寄存器,这些寄存器都可以当成剪切板来理解。通过:reg命令我们一般可以看多如下内容:

SSH+VIM 共享剪切板实现详解共享剪切板介绍

这里的每一行都是一个寄存器,其中0-9可以理解为是vim内部维护的10个独立剪切板,我们在使用y命令的时候实际上默认就在使用这个0号寄存器,1-9号寄存器实际上就是剪切板历史记录。这里我们需要重点了解的是*号和+号剪切板,通过;h registers帮助文档我们可以了解到这两个剪切板在vim编译时添加+xterm_clipboard特性才会支持,并且如果这两个剪切板不存在, 那么对他的所有操作都会默认重定向到0号剪切板上来。xterm_clipboard这个特性实际上就是指终端是否支持Xwindow实现的系统剪切,几乎现在所有Linux发行版的终端都支持这个特性。因此现代的vim一般都可以借助这两个寄存器来实现vim键盘命令来在操作Xwinow剪切板,其中的星号剪切对应是Xwindow的选择剪切板(鼠标选择时自动复制内容到这个剪切板),加号剪切对应的是和Win10上系统剪切板类似的复制剪切板(鼠标选择并按下复制快捷键后才会将选择的内容复制到这个复制剪切板),由于Windows上没有选择剪切板的概念,因此Win10上实现的Xserver程序默认都是直接将这两个剪切板映射的Windows唯一的系统剪切板上来。这个特性的结果就是如果配置好了Xwinodw共享剪切板,vim中操作这个两个剪切板任何一个都会触发Win10剪切板的更新,相反的,Win10下复制任何内容到系统剪切板都会触发vim中这两个剪切板的内容同时更新。

共享剪切板的实现配置

有了上面的基础概念后,我只需要做以下几个配置就可以实现共享剪切板了:

  1. Win10上选择一个Xserver程序并且配置好启动:这里个人推荐使用Mobaxterm,首先这个软件是免费绿色免安装的,第二它自带Xserver实现只需要简单勾选一下随程序启动就能实现正常的Xserver服务,配置截图类似如下:
    SSH+VIM 共享剪切板实现详解共享剪切板介绍
    通过如上的配置后只要Win10上运行着Mobaxterm就会自动提供一个Xserver服务,是不是很方便,毕竟Mobaxterm还有很多其他牛逼的功能嘛,这个Xserver只是顺便启动了一下(Mobaxterm是可以直接取代Putty实现ssh登陆的,因此实际上Windows端可以只启动一个Mobaxterm就能完成所有的远程登录操作,只可惜到目前为止最新的Mobaxterm 11.1 在vim设置了set termguicolors配置时依然存在光标消失的问题而导致我不得不继续使用Putty实现ssh登陆)。
  2. Linux开发主机上配置Xwindow使用远端的Xserver来替代本地的Xserver:

    大部分Linux发行版在图形界面启动时都是使用startx命令来启动Xwindow的,默认情况下发行版在图形启动时候总是会启动一个本地Xserver并且自动设置本地的图形界面使用本地的Xserver(毕竟图形界面主要的功能还是本地显示嘛),Xwinow指定Xserver的方式很简单,使用DISPLAY环境变量即可完成。当DISPALY=:0.0或者DISPLAY=:0时表示的是使用本地的Xserver,在Linux图形界面本地启动个终端并使用

    printenv|grep DISPLAY命令你应该能总使能看到该环境变量被默认设置成了:0/:0.0。为了使用Win10远端

    的Xserer我们只要需要重新 指定DISPLAY即可。

在你的~/.bashrc中添加如下配置以实现SSH登陆时总是能自动执行DISPLAY的配置:

export DISPLAY=4.25.6.23:0 #其中的ip修改为你自己Win10主机的ip。

  1. 修改vim的y、p命令默认使用共享剪切板:

    前面已经提到vim中y、p命令默认情况下使用的0号剪切板,想要使用星号或加号剪切板板得通过“*y/"*p来操作,这么费劲的操作自然是不乐意的,为了更加方便的使用共享剪切板,我们应该让配置vim默认使用星号或加号剪切板。

在你~/.vimrc中加入如下配置即可实现vim默认使用系统级剪切板:

set clipboard=unnamedplus,unnamed " 为了在多窗口见方面的复制粘贴, 这里选择默认使用’+'剪切板

  1. Win10建议额外使用一个更好的剪切板历史管理器:

    最新的Win10实际上已经提供了个剪切板历史管理功能,不过鉴于这个剪切板历史管理器没有搜索功能且管理的历史记录也不是太多,因此这里建议还是找一个更加专业的剪切板历史管理器使用的好,个人推荐Ditto这个软件,可绿化且功能强大,用了之后你一定会感谢我的。

本地虚拟机上共享剪切板的简化实现

上面提到的配置方式是通用的一个配置方式,不管是远程linux主机还是本地的linux虚拟机都是适用的,这个实现方案的一个缺点就是需要在本地的Win10主机上额外启动一个Xserver程序,像我这种由于Mobaxterm还存在BUG导致不得不继续使用Putty的情况,搞个开发还需同时启动两个程序,嗯,不是太开心。幸运的是,如果你像我一样,大部分开发都是Win10本地启动一个虚拟机然后再用SSH登陆这个虚拟机来干活的,则有一个更加方便简化的方法可以实现剪切板共享。

这个简化方法的实现首先要了解的是不管virtualbox还是vmware,大部分虚拟机软件都会提供一个增强工具,这个增强工具一般都会提供如下几个功能:

  1. 为虚拟机提供图形性能增强。 2. 提供一个共享目录功能。 3. 提供一个共享剪切板功能。

其中的第三点提供的共享剪切板功能可以理解为虚拟机会自动帮我们完成Win10主机系统剪切板和Linux虚拟客户机系统剪切板之间的同步操作,也就是指这里虚拟机程序替代了远端Xserver程序来为我们提供了共享剪切板能力。因此,如果我们仅仅是想实现个共享剪切板的功能自然不用在Win10上再启动个Xserver了。

有了如上的概念了解后,我们只需要做如下配置就可以完成在不启动Xserver的情况下实现共享剪切板的功能了:

  1. 指定SSH登陆本地虚拟机时总是使用本地的Xserver:

    默认情况下的Xwindow有这么一个特性:给本地图形界面指派DISPALY=:0(前提到过),给远程SSH登陆的终端自动指派DISPALY=localhost:10.0, 为什么会这么自动配置我也没怎么研究,总之这个配肯定是不能干活的,前面我们通过.bashrc中修改DISPLAY来实现将其配置成正确的远端主机,这里由于我们需要继续使用Linux本地Xserver提供的系统剪切板,因此我们应该在SSH登陆时将DISPALY变量继续保持为指向本地Xserver。

  2. 修复sudo vim命令中系统剪切板无效的问题

    Xwindow默认情况下还有个特性就是如果Xserver指向的是本地Xserver它总是默认不允许其他用户直接使用Xserever(这个限制在执行远端Xserver时是没有的,因此第一个实现方法中没有提及这个问题),这里的其他账户包括root,也就是说我们在用自己的账户登陆到linux系统后不管是通过sudo还是su切换到root账户Xserver总是自动被禁用了(验证这个问题的一个方法是sudo vim启动vim后通过;reg查看寄存器,你会发现*和+寄存器消失了)。这就导致了我们在使用sudo vim编辑一些/etc等系统文件时无法正常使用系统剪切板了,这个问题只要是在DISPLAY=:0时总是默认会有的,嗯,不是很爽。幸运的是,Xwindow提供了一个取消这个限制的命令:xhost + , 在使用sudo之前只需要执行一次这个命令,就能解除Xwindow对其他用户的限制。既然是只用执行一次,而且是普遍需要修复的问题,自然是放在~/.bashrc中自动配置最合适啦。

综合上面两点说明,我只需要在自己的~/.basrhrc中添加如下两个配置,就能实现本地虚拟机共享剪切板功能:

export DISPLAY=:0 # 将Xserver重定向到本地

xhost + > /dev/null # 授权其他用户可以使用本地的Xserver以保证系统剪切板在sudo操作使也能正常使用

当然,这个简化的方法只是避免了额外在Win10上启动一个Xserver的操作,第一个方法中的3、4步骤配置还是建议保持的。

好了, 通过上面的简单的配置,现在就已经可以愉快的在vim、sudo vim中使用使用共享剪切板板了。

enjoy it!

继续阅读