vim + COPY + mac 通过 SSH

Posted

技术标签:

【中文标题】vim + COPY + mac 通过 SSH【英文标题】:vim + COPY + mac over SSH 【发布时间】:2012-05-28 12:00:39 【问题描述】:

我通过 ssh 访问服务器,在该服务器上运行 vim 来编辑文件。当我尝试使用 y 或 "+y 将 vim 中的文本拉到我的 mac(lion)本地的编辑器中时,它不起作用。我最终得到了我最后在本地复制的文本。如果我只在其中使用 p 它确实有效vim 好了。

【问题讨论】:

您使用的是 Terminal.app 还是其他学期程序? 你能把名字改成 vim + COPY + mac over SSH 七年后.... 答案是创建 ~./vimrc 并添加一行:set clipboard = unnamed。这适用于 Mac 终端中的 debian 10。 【参考方案1】:

在您通过 ssh 进入的终端中拉动vi 内的行,将这些行复制到远程机器上 vi 的内部缓冲区,而不是 Mac 的剪贴板。

使用鼠标。 :)

【讨论】:

似乎应该有办法使用cmd+c,实际上尝试了鼠标,但效果不太好,而且速度很慢。我相信一定有更好的方法...... 是的,在终端窗口中,在运行 vi 的情况下,拖动鼠标以突出显示要复制的文本。点击 Command+C,然后在 Mac 上的本地应用程序中,例如 TextPad,点击 Command+V。 不起作用 - 这很明显。如果是这样,我不会在这里问。当我突出显示文本并说右键单击时,也可以使用鼠标返回仅选择我正在进行的特定工作。所以我只复制一个词。 抱歉,我想这很明显。我们必须有不同的配置,因为这确实对我有用。试试罗马尼的回答。最好的。 @evolution 只要未配置set mouse=a,它就可以工作。真正的问题是复制行号或每次复制时都必须关闭它们。编辑远程文件没问题:vim.wikia.com/wiki/Editing_remote_files_via_scp_in_vim【参考方案2】:

尝试其他剪贴板寄存器 - "*y

【讨论】:

【参考方案3】:

要扩展 Ray 的答案……

当你通过 SSH远程服务器上使用 Vim 时,你在 Vim 中所做的一切都是在远程服务器上完成的。远程服务器您在其上运行的远程 Vim 对您的本地计算机及其系统剪贴板的实际知识为零。

因此,y 永远不会将被拉出的文本放入本地剪贴板。

为了将一段文本远程 Vim 复制到你本地机器的剪贴板,你有三个选项:

用鼠标选择文本,然后像在任何 Mac OS X 应用程序中一样点击 Cmd+C

显然,它似乎是最简单的,但它至少有三个限制:

    仅限于当前屏幕。如果您要拉出的文本未完全显示,您将无法全部复制。

    它不能很好地与set mouse=a 配合使用。使用此选项,任何用鼠标选择内容的尝试都将导致 visual 模式选择,该模式选择无法使用 Cmd+C 进行复制.作为一种解决方法,您可以使用 Alt+鼠标选择文本而不进入 visual 模式,或者直接从远程 ~/.vimrc 删除此设置。

    李>

    行号也会被复制。

将抽出的文本放入一个临时文件中,scp 将其放入您的本地计算机,然后使用 pbcopy 将其放入您的系统剪贴板中。

这个解决方案似乎有点复杂,但它确实有效(而且问题本身也有点复杂)。多年来,我看到了很多不同的实现,从简单的单列到客户端/服务器设置。 Here is one,请随时用谷歌搜索其他人。

使用 X-forwarding 将本地剪贴板连接到远程剪贴板(如果可用)。

【讨论】:

谢谢 Romaini - 我认为这是最接近的答案。似乎确实没有很好的答案。我确实有鼠标=a。我希望保留它。由于我还想保持书呆子树的打开状态,按下 Alt 我不仅可以获取行号,还可以获取目录。要么真的很糟糕。我碰巧也使用Expanddrive mac。我将 .vimrc 和 .vim 目录移到 mac 上并通过 sftp 访问。无论我尝试什么,仍然 yank 不起作用 - 所以我加入了这个 hack “vmap y :w !pbcopy”。这非常接近完美。奇怪的小错误是你只能复制 FULL 行... 帮助提示:使用“用鼠标选择文本”选项时,您可以使用 :set nonum 切换行号。 另一种方法很笨重,但可以在紧要关头工作:退出 vim。命令行中的“cat”文件(键入“cat ”)。现在你可以用鼠标(和 cmd-C)复制了。 在某些操作系统上,当使用鼠标选择文本时需要按住 shift 而不是 alt 来覆盖 set mouse=a 按住 alt,使用鼠标选择,Cmd+C 在 mac 上运行良好!谢谢!【参考方案4】:

我的首选解决方案是通过 scp 在本地计算机上使用 vim 编辑文件。

:e scp://remoteuser@server.tld//path/to/document

这使您的缓冲区保持在本地,并且可以轻松复制到本地剪贴板。

另一个优点是您可以使用本地 vim 设置(.vimrc 设置、插件等)

【讨论】:

好方法,可惜当你在 SSH 会话中的 docker 容器外壳中时它不起作用。【参考方案5】:

这是来自 romainl 的解决方案 #2 的更新。它创建 ssh 命令的别名并在 remotecopyserver 未运行时启动它,并将 remotecopy(rclip) 安装在远程服务器中。简而言之,除了将下面的代码 sn-p 粘贴到 bash_profile 中之外,您无需执行任何操作。

######################## For SSH Remote Copy #########################
export LC_SETUP_RC='command -v rclip >/dev/null 2>&1 ||  echo "executing"; mkdir -p /usr/local/bin; if [ ! -f /usr/local/bin/rclip ];then wget https://raw.githubusercontent.com/justone/remotecopy/master/remotecopy -P /usr/local/bin/; ln -s /usr/local/bin/remotecopy /usr/local/bin/rclip; chmod +x /usr/local/bin/remotecopy; fi; if [[ \":\$PATH:\" == *\"/usr/local/bin:\"* ]]; then export PATH=/usr/local/bin:$PATH; fi  > /var/log/rclip.log 2>&1 || echo "Some error occured in setting up rclip. check /var/log/rclip.log"'

ssh_function() 
count="`ps -eaf | grep remotecopyserver | grep -v grep | wc -l`";
if [ "$count" -eq "0" ]; then 
   mkdir -p $HOME/bin;
   if [ ! -f $HOME/bin/remotecopyserver ]; then 
      wget https://raw.githubusercontent.com/justone/remotecopy/master/remotecopyserver -P $HOME/bin;
      chmod +x $HOME/bin/remotecopyserver;
   fi;
   nohup $HOME/bin/remotecopyserver & 
fi;
ssh_cmd=`which ssh`
PARAMS=""
for PARAM in "$@"
do
  PARAMS="$PARAMS \"$PARAM\""
done
bash -c "ssh $PARAMS -R 12345:localhost:12345 -t 'echo \$LC_SETUP_RC | sudo bash; bash -l'"

alias ssho=`which ssh`
alias ssh=ssh_function
alias ssh2=ssh_function

vssh_function() 
ssh_config=`vagrant ssh-config`;
if [ "$?" -eq "1" ]; then
echo "Problem with Vagrant config. run 'vagrant ssh-config' to debug"
return 1
fi
PORT=`echo "$ssh_config" | grep Port | grep -o "[0-9]\+"`; 
ID_FILE=`echo "$ssh_config" | grep IdentityFile | awk 'print $2'`
ssh2 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o PasswordAuthentication=no -i $ID_FILE vagrant@localhost -p $PORT "$@"

alias vssh=vssh_function

一旦别名被激活,你可以正常使用 ssh 并且当你需要从 vim 复制到本地剪贴板时,使用

:w !rclip 

将整个文件复制到剪贴板

:'<,'> !rclip

从视觉模式复制选定的行。每当它要求输入密钥时,您必须按“Cmd+V”或“Ctrl+V”。

奖金

对于那些从事 Vagrant 工作的人,有一个包装器 vssh 将执行 vagrant ssh 但也会启动并安装必要的组件。

参考

最新代码 sn-p 在这里 - https://gist.github.com/ningsuhen/7933b206b92fc57364b2

http://endot.org/2011/12/04/remotecopy-copy-from-remote-terminals-into-your-local-clipboard/

https://github.com/justone/remotecopy

注意事项

别名包装了 ssh 命令,可能会出现一些意想不到的问题。如果您需要在没有整个 remotecopyserver 的情况下执行 ssh,则可以使用ssho。或者,您可以使用别名 ssh2 并保持 ssh 命令不变。

【讨论】:

【参考方案6】:

遇到了这个问题 - 通过 SSH 从 OSX 登录到 linux 机器,并且无法从使用 vim 打开的文件中复制文本。

我的解决方法是:set mouse=i

默认情况下,鼠标在所有模式下都启用。当您将其设置为仅在插入模式下启用时,您可以在不编辑时滚动和复制(正常模式),但当您开始编辑(通过按 I 或插入键)并进入插入模式时,鼠标充当光标放置而且你不能从终端复制。

您可以在 ~/.vimrc 中设置该选项

有关可以设置的值和模式的更多信息,请参阅 :help mouse。

【讨论】:

使用:set mouse=i 也对我有用。在不指定任何mouse相关属性的情况下,使用鼠标选择启用文本的可视模式。单独运行:set,这显示为唯一的鼠标:ttymouse=xterm2。请注意,在我运行 :set mouse=i 之后,ttymouse=xterm2 仍然存在,但我可以使用鼠标选择文本并使用 Mac 剪贴板进行复制。 谢谢,这解决了我的问题。如果我想调整拆分,我必须切换 mouse=a|i,但这很简单,而且很有效。【参考方案7】:

我在 *** 上的第一个答案,但我觉得这是一个很酷(虽然很小)的技巧,值得发布。所以这就是我要做的:

cat <filename>

当文本打印到终端时,我用鼠标选择所有文本(鼠标滚动工作,因为我们在终端窗口上)。然后使用Cmd+C 复制该文本并粘贴到我的本地文本编辑器中。

此技巧的唯一缺陷是,如果您的文件有数万行长,则使用它是不切实际的,因为用鼠标选择所有行本身就是一项任务。但是对于大约 2k 行的文件,它运行良好。

【讨论】:

如果有人想粘贴而不是复制,请执行!cat &gt;&gt; %,粘贴,然后按 ctrl-C 停止 cat。运行:e!,内容应该出现在文件底部。 如果你只是想复制,比如说从 2k 行文件中的第 750 到 764 行,你可以在 vim 命令行中执行 ! cat % | head -764【参考方案8】:

或者,从终端写入less [filename] 以将其写入终端。然后用鼠标开始选择,同时按住down-arrow-key。然后你可以选择整个一堆。

【讨论】:

谢谢。您的技巧适用于需要滚动的大量内容。不幸的是,它只适用于向下箭头键。不使用 G 键(直到文件末尾)【参考方案9】:

如果行数很少溢出我的屏幕,我在使用鼠标复制 vim 文本时经常使用的一个技巧是 最小化 (Cmd + '-') 文本。 :) 尽量减少到肉眼看不到的程度,但可以一次性复制所有文本。

【讨论】:

哇,这实际上非常实用。【参考方案10】:

在 MacOS 上,当从机器 A SSH 到机器 B 并在机器 B 中使用 vim 时,我将其添加到机器 B 中的 .vimrc

nmap yr :call system("ssh $machineA_IP pbcopy", @*)<CR>

这样,在普通模式下,如果你复制一些东西到*寄存器,然后输入yr,vim@machine_B中*寄存器的内容会被复制到机器A的本地剪贴板,假设你已经正确设置了Vim +clipboard* 注册

【讨论】:

【参考方案11】:

iTerm2 Shell 实用程序带有it2copy,它允许从远程服务器复制到客户端剪贴板。在远程服务器上安装 Shell Utilities 并确保您已选中 Applications in terminal may access clipboard

然后,进入visual mode,选择文本并执行&lt;,'&gt;:w !it2copy

【讨论】:

有趣。我现在使用 neovim 而不是 vim,但最近没有尝试过。我会调查的。 你如何在远程服务器上安装命令? @David542 我的回复有点晚......你需要在服务器上install shell integration 这似乎不起作用!我得到zsh:1: command not found: it2copy @andrewgazelka 很抱歉回复晚了,是的,我做到了,但取得了一些成功,但我正在接受 base64 格式的测试。我在 iterm repo 中做了 PR,但帮助不大:\github.com/gnachman/iterm2-website/issues/81【参考方案12】:

我希望在这里改进我​​的解决方案,但我会分享它,因为它似乎与其他一些解决方案相当。

在 Mac 上使用 iTerm2,连接到机器,运行 tmux,然后使用 Vim 编辑时,我在 Mac 上有一个垂直拆分的 iTerm2 窗口,我将它拉到一边,使其尽可能瘦.

然后,当我想从 Vim 复制文本时,我将单击 iTerm2 窗口的一小部分,然后返回并突出显示,然后从 Vim 复制文本。这最适合单行文本。

如果有 tmux 垂直分割,高亮显示 Vim 缓冲区中的多行将无法正确换行,并且会从另一个 tmux 窗口复制文本,但否则这对于复制我需要的 90% 的内容非常有用,而无需退出 Vim、cat 文件或执行其他操作。

我还有充足的水平窗口空间,让 iTerm2 的小窗口不占空间。

【讨论】:

【参考方案13】:

只需使用 MobaXterm。 我尝试了很多方法,但没有一个是容易的。所以我能找到的唯一解决方案是使用 MobaXterm。您可以查看所有文件并以任何您想要的方式打开它们。

【讨论】:

【参考方案14】:

https://github.com/ojroques/vim-oscyank + iTerm2 + tmux 在我的情况下工作,这是我的工作流程:

ssh 进入远程主机 打开一个新的 tmux 会话 打开 vim(或 neovim),https://github.com/ojroques/vim-oscyank 已按照文档说明安装和配置

我的 .vimrc 的某些部分

Plug 'ojroques/vim-oscyank'  " clipboard over ssh through tmux

" yank operation don't need to use the *" register (system clipboard)
set clipboard+=unnamedplus

autocmd TextYankPost * if v:event.operator is 'y' && v:event.regname is '' | OSCYankReg " | endif

【讨论】:

嘿,这太棒了,一直在寻找解决方案,现在可以在运行 iTerm 的 mac 上完美运行,通过 ssh 连接到在 tmux 中运行 vim 的 linux 服务器,完美。谢谢!

以上是关于vim + COPY + mac 通过 SSH的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Mac 上安装 ssh-copy-id?

scp ssh-copy-id 无法通过通过root 用户发送文件或公钥解决办法

CentOS7开启ssh服务

Mac centos7基本的环境配置

Mac如何远程连接Ubuntu主机ssh连接|Mac通过ssh远程连接Ubuntu主机

Mac系统下 查看或者生成 ssh