如何从远程SSH会话将数据发送到本地剪贴板


161

Borderline ServerFault问题,但是我正在编程一些shell脚本,所以我先在这里尝试:)

大多数* nixes都有一个命令,可让您通过管道将输出重定向/重定向到本地剪贴板/粘贴板,并从中进行检索。在OS X上,这些命令是

pbcopy, pbpaste 

无论如何,在通过SSH连接到另一台服务器时是否可以复制此功能?那是,

  1. 我正在使用计算机A。
  2. 我打开一个终端窗口
  3. 我通过SSH连接到计算机B
  4. 我在计算机B上运行命令
  5. 计算机B的输出将被重定向或自动复制到计算机A的剪贴板中。

是的,我知道我可以(使用鼠标)从命令中选择文本,但是我已经习惯了将输出直接拖到剪贴板的工作流程,因此我希望对远程会话也是如此。

代码是有用的,但是一般的方法也是可以理解的。

Answers:


89

我正在恢复该线程,因为我一直在寻找相同的解决方案,并且已经找到了一种适合我的解决方案。这是对OSX Daily的建议的较小修改。

就我而言,我使用本地OSX计算机上的Terminal通过SSH连接到linux服务器。像OP一样,我希望能够仅使用键盘将少量文本从终端传输到本地剪贴板。

解决方案的实质:

commandThatMakesOutput | ssh desktop pbcopy

在与远程计算机的ssh会话中运行时,此命令采用commandThatMakesOutput的输出(例如ls,pwd),并将输出通过管道传输到本地计算机的剪贴板(“桌面”的名称或IP)。换句话说,它使用嵌套的ssh:您通过一个ssh会话连接到远程计算机,然后在其中执行命令,然后远程计算机通过另一个ssh会话连接到桌面,并将文本放入剪贴板。

它要求将您的桌面配置为ssh服务器(我留给您和Google使用)。如果您已经设置了ssh密钥来促进ssh的快速使用,则要容易得多,最好使用每个会话的密码短语,或者任何您需要的安全性。

其他例子:

ls  | ssh desktopIpAddress pbcopy
pwd |  ssh desktopIpAddress pbcopy

为了方便起见,我创建了一个bash文件来缩短管道后所需的文本:

#!/bin/bash
ssh desktop pbcopy

就我而言,我使用的是特殊命名的密钥

我用文件名cb(我的助记符(ClipBoard))保存了该脚本。将该脚本放在您的路径中的某个位置,使其可执行并可以执行以下操作:

ls | cb

3
我经常在vim中对此。这样做,选择要在可视模式下复制的内容,然后键入::'<,'>w !ssh desktop pbcopy
Mike Brennan

@MikeBrennan选择了文本后,为什么不按cmd + C(或您设置的任何复制键)呢?...
Petr Peller

36
这样,它只有在您的桌面具有静态IP并且可以从ssh插入的盒子中访问时才真正起作用。对我而言,从来都不是这样。
kqw 2014年

6
反过来会更容易吗?ssh user @ remote'commandThatMakesOutput'| pbcopy
rulio 2014年

我需要的-e noneSSH标志说明如下:unix.stackexchange.com/questions/210615/...
帕特迈伦

122

我最喜欢的方式是 ssh [remote-machine] "cat log.txt" | xclip -selection c。当您不想(或不能)从远程到本地ssh时,这是最有用的。

编辑:在Cygwin ssh [remote-machine] "cat log.txt" > /dev/clipboard

编辑:来自nbren12的有用评论:

几乎总是可以使用SSH端口转发来建立反向ssh连接。只需添加RemoteForward 127.0.0.1:2222 127.0.0.1:22到本地服务器的条目中.ssh/config,然后ssh -p 2222 127.0.0.1在远程计算机上执行,远程计算机将把连接重定向到本地计算机。– nbren12


6
+1:在无法进行反向SSH连接时,比其他解决方案容易得多!
John Dibling 2014年

9
极简单的解决方案值得您更多的喜欢!
Kamil Dziedzic 2014年

31
对于我们在Mac OSX上的用户,ssh [remote-machine] "cat log.txt" | pbcopy
2014年

1
根据此处的报告,我必须使用cat它才能在cygwin Windows 8上运行:(ssh [remote-machine] "cat log.txt" | cat > /dev/clipboard当然,我的远程命令不是cat;它是在无所事事的虚拟机中的其他东西,所以我实际上在vagrant ssh -c "command" | cat > /dev/clipboard
tiby

7
几乎总是可以设置使用SSH端口转发的反向ssh连接。只需添加RemoteForward 127.0.0.1:2222 127.0.0.1:22到local的服务器条目中.ssh/config,然后ssh -p 2222 127.0.0.1在远程计算机上执行,然后该远程计算机会将连接重定向到本地计算机。
nbren12 '16

30

找到了不需要反向ssh连接的绝佳解决方案!

您可以在远程主机上使用xclip,在OSX系统上使用ssh X11转发和XQuartz。

要进行设置:

  1. 安装XQuartz(我使用soloist + ivotal_workstation :: xquartz配方完成此操作,但您不必这样做)
  2. 运行XQuartz.app
  3. 打开XQuartz首选项(kb_command+ ,
  4. 确保选中 “启用同步”“ CLIPBOARD更改时更新粘贴板”XQuartz首选项窗口示例
  5. ssh -X remote-host "echo 'hello from remote-host' | xclip -selection clipboard"

1
这有什么不同ssh remote-host "echo 'hello from remote-host' | pbcopy?如果它将像这样工作,这将是一个很好的答案: ssh -X remote-host然后在远程主机上:echo 'hello from remote-host' | xclip -selection clipboard
kqw 2014年

5
@KasperSouren。我相信它确实可以满足您的期望。`| xclip`在双引号内。
gdw2

1
在2016年,这显然是最好的,简洁的解决方案。忘记其他基于反向SSH的解决方案。
shivams

1
有没有办法只做一个一次性命令就可以做到这一点?我想通过ssh在交互式会话中登录到远程服务器,然后能够将其任意发送到本地剪贴板。这需要反向ssh吗?
克瓦斯

2
@Kvass:只要您-X用于通过SSH进行X11转发,X11程序就可以通过上面的XQuartz设置更新剪贴板。一次性命令是要演示通过echo将数据发送到远程主机的剪贴板xclip确实可行,并且应同步到本地SSH客户端主机。注意,如@ gdw2所说,“ The | xclip在双引号内”。这样,它将作为远程服务器上的命令执行,以将某些内容发送到剪贴板。
TrinitronX

18

SSH服务器上的反向隧道端口

所有现有解决方案都需要:

  • 客户端上的X11(如果有的话,xclip在服务器上也可以正常工作)或
  • 客户端和服务器位于同一网络中(如果您在工作中尝试访问家用计算机,则不是这种情况)。

这是另一种方法,尽管您需要修改ssh进入计算机的方式。

我已经开始使用它了,它看起来似乎没有那么吓人,因此请尝试一下。

客户端(SSH会话启动)

ssh username@server.com -R 2000:localhost:2000

(提示:将此设置为键盘绑定,因此您无需键入它)

客户端(另一个选项卡)

nc -l 2000 | pbcopy

注意:如果没有,pbcopy则仅将tee其保存到文件中。

服务器(在SSH会话内部)

cat some_useful_content.txt | nc localhost 2000

其他注意事项

实际上,即使您正处于ssh会话的中间,也有一种方法可以启动隧道,但是我不想吓到人们远离看起来并不那么糟糕的地方。但如果有兴趣,我会在稍后添加详细信息


1
+1-非常整洁。但是- cat some_useful_content.txt | nc localhost 2000当我这样做时,命令似乎挂起。我需要手动按ctr-c停止它,只有这样内容才能到达我的客户端剪辑/粘贴板上
Alan Storm

1
它将等待,直到有人将另一端的数据出队。
Sridhar Sarnobat

其实我想我误会了你的问题。我不确定为什么会这样。
Sridhar Sarnobat,

nc -l -p为我工作,但nc -l没有。我也有@AlanStorm的问题。
HappyFace

1
我通过指定解决了挂网猫的问题-c。我使用brew安装的GNU netcat。
HappyFace

7

有多种工具可以访问X11选择,包括xclipXSel。请注意,X11传统上具有多个选择,并且大多数程序对剪贴板和主要选择都有一定的了解(这是不相同的)。Emacs也可以与辅助选择一起使用,但这很罕见,而且没人真正知道如何使用剪切缓冲区。

$ xclip-帮助
用法:xclip [OPTION] [FILE] ...
访问用于读取或写入的X服务器选择。

  -i,-in从标准输入或文件中将文本读入X选择
                   (默认)
  -o,-out将选择输出到标准输出(通常用于
                   管道到文件或程序)
  -l,-循环退出前要等待的选择请求的数量
  -d,-display要连接的X显示(例如localhost:0“)
  -h,-帮助用法信息
      -选择访问的选择(“主要”,“次要”,“剪贴板”或“缓冲区剪切”)
      -noutf8不要将文本视为utf-8,请使用旧的unicode
      版本信息
      -仅静默错误,在后台运行(默认)
      -在前台安静运行,显示正在发生的事情
      -详细的运行注释

向<astrand@lysator.liu.se>报告错误
$ xsel-帮助
用法:xsel [选项]
操纵X选择。

默认情况下,当前选择是输出,如果两个都选择则不修改
标准输入和标准输出是端子(ttys)。除此以外,
如果标准输出不是端子,则输出当前选择
(tty),并且如果标准输入,则从标准输入设置选择
不是终端(tty)。如果给出任何输入或输出选项,则
该程序仅在请求的模式下运行。

如果同时需要输入和输出,则先前的选择是
输出,然后替换为标准输入的内容。

输入选项
  -a,--append将标准输入附加到选择项
  -f,--follow随着标准输入的增加而追加到选择
  -i,--input将标准输入读入选择

输出选项
  -o,--output将选择内容写入标准输出

动作选项
  -c,--clear清除选择
  -d,--delete请求清除选择并
                        拥有它的应用程序删除其内容

选择选项
  -p,--primary在PRIMARY选择上操作(默认)
  -s,--secondary在SECONDARY选择上操作
  -b,--clipboard在CLIPBOARD选项上操作

  -k,--keep不要修改选择,而是设为PRIMARY
                        和SECONDARY选择即使在
                        程序在退出时被选中。
  -x,--exchange交换PRIMARY和SECONDARY选择

X选项
  --display displayname
                        指定与X服务器的连接
  -t ms,--selectionTimeout ms
                        指定超时时间(以毫秒为单位)
                        选择必须被检索。值0(零)
                        指定没有超时(默认)

杂项选项
  -l,--logfile指定文件,以便在分离时记录错误。
  -n,--nodetach不与控制终端分离。不带
                        此选项,xsel将分叉成为背景
                        在输入,交换和保留模式下进行处理。

  -h,--help显示此帮助并退出
  -v,--verbose打印信息性消息
  --version输出版本信息并退出

请向<conrad@vergenet.net>报告错误。

简而言之,您应该根据自己的需要尝试xclip -i/ xclip -oxclip -i -sel clip/ xclip -o -sel clipxsel -i/ xsel -oxsel -i -b/ xsel -o -b


4
要添加到@ephemient的帖子中:为了将xclip&xsel与远程主机一起使用,您可以像这样使用X11转发:ssh -C -X user@remote-host。如果在远程端运行xclip似乎不起作用,请确保X11Forwarding yes在远程/etc/ssh/sshd_config文件中已设置。还要确保xauth安装在远程侧。对于无头机器,您可以安装xauthxvfb
TrinitronX

这里的描述与额外的细节加上vim的键绑定。
Tim Bunce 2012年

1
@TrinitronX哦,哇-将我的头撞在墙上,多谢xvfb提及。我正在运行无头服务器,因此X11一定没有在运行!
凸轮

5

这是我基于SSH反向隧道,netcat和xclip的解决方案。

首先在您的工作站上创建脚本(例如,剪贴板-daemon.sh):

#!/bin/bash
HOST=127.0.0.1
PORT=3333

NUM=`netstat -tlpn 2>/dev/null | grep -c " ${HOST}:${PORT} "`
if [ $NUM -gt 0 ]; then
    exit
fi

while [ true ]; do
    nc -l ${HOST} ${PORT} | xclip -selection clipboard
done

并在后台启动它。

./clipboard-daemon.sh&

接收到部分数据后,它将开始nc管道输出到xclip并重新生成过程

然后开始ssh连接到远程主机:

ssh user@host -R127.0.0.1:3333:127.0.0.1:3333

在远程框中登录时,请尝试以下操作:

echo "this is test" >/dev/tcp/127.0.0.1/3333

然后尝试粘贴到您的工作站上

当然,您可以编写包装程序脚本,该脚本首先启动剪贴板-daemon.sh,然后启动ssh会话。这就是我的工作方式。请享用。


此解决方案是最适合我的解决方案。它并不太复杂并且可以正常工作。
Marcel Valdez Orozco

我认为最好的解决方案。您不必担心允许反向ssh连接,这会带来安全隐患,并且无限循环是一种不错的选择。
R. Taukulis

4

不是单线的,但不需要额外的ssh

  • netcat必要时安装
  • 使用termbincat ~/some_file.txt | nc termbin.com 9999。这会将输出复制到termbin网站,并将URL打印到您的输出。
  • 从您的计算机访问该网址,您将得到输出

当然,请勿将其用于敏感内容。


哇,这是一个非常有创意的解决方案。
Sridhar Sarnobat,

3

通过增加安全性,此答案可在所选答案的基础上发展。

该答案讨论了一般形式

<command that makes output> | \
    ssh <user A>@<host A> <command that maps stdin to clipboard>

当安全可能会缺乏的是在ssh允许的权限<user B>host B>,以ssh进入host A并执行任意命令。

当然BA访问可能已经由ssh密钥来控制,甚至可能具有密码。但是另一层安全性可以限制B可以在上执行的允许命令的范围A,例如,使得这些命令rm -rf /不能被调用。(当ssh密钥没有密码时,这尤其重要。)

幸运的是,它ssh具有称为命令限制强制命令的内置功能。请参阅ssh.com或此serverfault.com问题

下面的解决方案显示了常规形式的解决方案以及强制执行的ssh 命令限制

添加命令限制的示例解决方案

这种增强安全性的解决方案遵循一般形式-从ssh会话开始的调用host-B很简单:

cat <file> | ssh <user-A>@<host A> to_clipboard

其余的内容显示了使之生效的设置。

设置ssh命令限制

假设上的用户帐户Buser-B,并且B具有ssh密钥id-clip,该密钥已以通常的方式(ssh-keygen)创建。

然后在user-Assh目录中有一个文件

/home/user-A/.ssh/authorized_keys

识别密钥id-clip并允许ssh连接。

通常,每行的内容authorized_keys都是授权的公钥,例如的内容id-clip.pub

但是,为了强制执行命令限制,要执行的命令(在同一行上)将公共密钥内容放在前面。
在我们的情况下:

command="/home/user-A/.ssh/allowed-commands.sh id-clip",no-agent-forwarding,no-port-forwarding,no-user-rc,no-x11-forwarding,no-pty <content of file id-clip.pub>

指定的命令"/home/user-A/.ssh/allowed-commands.sh id-clip",并且是指定命令,每当关键是执行id-clip用于发起ssh到连接host-A- 无论什么命令写在ssh命令行

该命令指示一个脚本文件allowed-commands.sh,该脚本文件的内容为

#/bin/bash
#
# You can have only one forced command in ~/.ssh/authorized_keys. Use this
# wrapper to allow several commands.

Id=${1}

case "$SSH_ORIGINAL_COMMAND" in
    "to-clipboard")
          notify-send "ssh to-clipboard, from ${Id}"
        cat | xsel --display :0 -i -b
          ;;
    *)
        echo "Access denied"
        exit 1
        ;;
esac

最初ssh在计算机上致电B

... | ssh <user-A>@<host A> to_clipboard

该字符串由环境变量to-clipboard传递给。另外,我们从仅由进行访问的行中传递了密钥的名称。allowed-commands.shSSH_ORIGINAL_COMMANDid-clipauthorized_keysid-clip

线

          notify-send "ssh to-clipboard, from ${Id}"

只是一个弹出消息框,让您知道剪贴板正在写入-这可能也是一项很好的安全功能。(notify-send可在Ubuntu 18.04上使用,也许不能在其他版本上使用)。

在行中

cat | xsel --display :0 -i -b

该参数--display :0是必需的,因为该过程没有自己的带有剪贴板的X显示,因此必须明确指定它。此值:0恰好在具有Wayland窗口服务器的Ubuntu 18.04上工作。在其他设置上,它可能不起作用。对于标准X服务器,此答案可能会有所帮助。

host-A /etc/ssh/sshd_config 参数

最后,应/etc/ssh/sshd_config在主机A上设置一些参数,以确保连接权限以及ssh仅在没有密码的情况下使用-key的权限:

PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
AllowUsers user-A

使sshd服务器重新读取配置

sudo systemctl restart sshd.service

要么

sudo service sshd.service restart

结论

进行设置需要一些努力,但是to-clipboard可以在同一框架中并行构造其他功能。


1
带有remoteforwarding的Xsel是在本地运行i3的Ubuntu 18.04上对我有用的唯一答案。无需X11转发。
杰伊·斯坦利


2

最简单的解决方案是,如果您使用的是使用Terminal的OS X,并且一直在远程服务器中闲逛,并且希望获取文本文件,日志或csv的结果,则只需:

1)Cmd-K清除终端的输出

2)cat <filename>显示文件内容

3)Cmd-S保存终端输出

您将手动删除文件的第一行和最后一行,但是此方法比依赖于要安装的其他软件包,“反向隧道”和尝试具有静态IP等要简单一些。


+1是我自己使用的一种有用技术,它确实会迫使您丢失终端历史记录,并且(如前所述)第一行/最后一行问题有点麻烦。
艾伦·斯托姆

同意@AlanStorm
tw0000

这种方法更重要的问题是,它将只保存终端缓冲区保留的行数。通常这不是问题,但是如果您尝试获取日志文件的内容,则可能会用光容量,
Sridhar Sarnobat

没错,@ Sridhar-Sarnobat,这通常不是一个很好的解决方案。我只是用scp
tw0000
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.