如何从远程 SSH 会话将数据发送到本地剪贴板
Posted
技术标签:
【中文标题】如何从远程 SSH 会话将数据发送到本地剪贴板【英文标题】:How to send data to local clipboard from a remote SSH session 【发布时间】:2010-11-12 05:57:34 【问题描述】:Borderline ServerFault 问题,但我正在编程一些 shell 脚本,所以我先在这里尝试 :)
大多数 *nixes 都有一个命令,可以让您通过管道/重定向输出到本地剪贴板/粘贴板,并从中检索。在 OS X 上,这些命令是
pbcopy, pbpaste
在通过 SSH 连接到另一台服务器时是否可以复制此功能?也就是说,
-
我正在使用计算机 A。
我打开一个终端窗口
我通过 SSH 连接到计算机 B
我在计算机 B 上运行命令
计算机 B 的输出被重定向或自动复制到计算机 A 的剪贴板。
是的,我知道我可以(颤抖)使用鼠标从命令中选择文本,但我已经习惯了将输出直接传输到剪贴板的工作流程,我希望我的遥控器也一样会议。
代码很有用,但一般方法也很受欢迎。
【问题讨论】:
我在 Linux 上回答了一个类似的问题 here,与 @TrinitronX 类似,但没有 XQuartz。 【参考方案1】:如果您在 Mac 上使用iTerm2,有一种更简单的方法。此功能通过it2copy
命令内置于iTerm2 的Shell Integration 功能中:
Usage: it2copy
Copies to clipboard from standard input
it2copy filename
Copies to clipboard from file
要使其工作,请在登录远程主机时选择iTerm2-->Install Shell Integration菜单项,将其安装到您自己的帐户中。完成后,您将可以访问it2copy
,以及一系列其他提供酷炫功能的别名命令。
这里的其他解决方案是很好的解决方法,但相比之下,这个解决方案非常轻松。
【讨论】:
【参考方案2】:请允许我添加一个解决方案,如果我没记错的话,之前没有建议过。 它涉及:
-
在远程主机上创建一个 fifo 文件。
打开与远程主机的连接和另一个在该 fifo 上并行等待的连接。
您在该 fifo 文件中回显的任何内容最终都会出现在您的本地剪贴板中。
会话完成后,立即终止连接。
它利用 ssh 的 ControlMaster 功能来避免连接开销并为您提供干净的连接终止。
此外,远程主机没有特殊要求(例如 x 个库)。
编辑:根据要求,代码本身:
将以下内容粘贴到您的 bashrc 中并使用 sshx host
进行连接。
在远程机器 echo SOMETHING > ~/clip
上,希望 SOMETHING 最终会出现在本地主机的剪贴板中。
您将需要本地主机上的 xclip
实用程序。
_dt_term_socket_ssh()
ssh -oControlPath=$1 -O exit DUMMY_HOST
function sshx
local t=$(mktemp -u --tmpdir ssh.sock.XXXXXXXXXX)
local f="~/clip"
ssh -f -oControlMaster=yes -oControlPath=$t $@ tail\ -f\ /dev/null || return 1
ssh -S$t DUMMY_HOST "bash -c 'if ! [ -p $f ]; then mkfifo $f; fi'" \
|| _dt_term_socket_ssh $t; return 1;
(
set -e
set -o pipefail
while [ 1 ]; do
ssh -S$t -tt DUMMY_HOST "cat $f" 2>/dev/null | xclip -selection clipboard
done &
)
ssh -S$t DUMMY_HOST \
|| _dt_term_socket_ssh $t; return 1;
ssh -S$t DUMMY_HOST "rm $f"
_dt_term_socket_ssh $t
更详细的解释在我的网站上:
https://xicod.com/2021/02/09/clipboard-over-ssh.html
【讨论】:
虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review @radrow 感谢您的评论,我更新了答案【参考方案3】:如果您正在加班,例如Kubernetes 集群中的一个 pod 而不是直接 SSH,因此您无法进行文件传输,您可以使用 cat
然后将终端输出保存为文本。例如,在 macOS 中,您可以执行 Shell -> Export as text。
【讨论】:
【参考方案4】:对于任何通过谷歌搜索的人: 这个时代最好的解决方案似乎是lemonade
clipboard-tool的neovim帮助文本中也提到了各种解决方案
【讨论】:
【参考方案5】:Far Manager Linux port 支持在本地和远程主机之间同步剪贴板。您只需打开本地 far2l,在里面执行“ssh somehost”,在该 ssh 会话中运行远程 far2l,然后让远程 far2l 与本地剪贴板一起工作。
它支持Linux、*BSD和OS X;我创建了一个special putty build 以在 Windows 中使用此功能。
【讨论】:
【参考方案6】:这个答案在chosen answer 的基础上增加了更多的安全性。
那个答案讨论了一般形式
<command that makes output> | \
ssh <user A>@<host A> <command that maps stdin to clipboard>
可能缺乏安全性的地方是ssh
权限允许host B>
上的<user B>
到ssh
进入host A
并执行any 命令。
当然,B
到 A
的访问可能已经被 ssh
密钥所限制,甚至可能有密码。但是另一层安全性可以限制B
可以在A
上执行的允许命令的范围,例如这样rm -rf /
就不能被调用。 (当ssh
键没有有密码时,这一点尤其重要。)
幸运的是,ssh
有一个称为命令限制或强制命令的内置功能。请参阅ssh.com,或
这个serverfault.com question。
下面的解决方案显示了通用表单解决方案以及强制执行的ssh
命令限制。
添加了命令限制的示例解决方案
此安全增强解决方案遵循一般形式 - 来自 host-B
上的 ssh
会话的调用很简单:
cat <file> | ssh <user-A>@<host A> to_clipboard
剩下的部分显示了让它工作的设置。
ssh命令限制设置
假设B
上的用户帐户是user-B
,并且B 有一个ssh 密钥id-clip
,它是以通常的方式创建的(ssh-keygen
)。
然后在user-A
的ssh目录下有个文件
/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
启动与host-A
的ssh
连接时执行 - 不管是什么命令写在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
在机器 B
上对 ssh
的原始调用是
... | ssh <user-A>@<host A> to_clipboard
字符串to-clipboard
由环境变量SSH_ORIGINAL_COMMAND
传递给allowed-commands.sh
。
此外,我们从authorized_keys
的行中传递了密钥的名称id-clip
,只有id-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 服务器this answer 可能会有所帮助。
host-A
/etc/ssh/sshd_config
参数
最后应该设置主机A
上的/etc/ssh/sshd_config
中的几个参数,以确保允许连接,并允许使用ssh
-key,无需密码:
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
AllowUsers user-A
让sshd
服务器重新读取配置
sudo systemctl restart sshd.service
或
sudo service sshd.service restart
结论
设置起来有点费力,但是除了to-clipboard
之外的其他功能可以在同一个框架中并行构建。
【讨论】:
具有远程转发功能的 Xsel 是在本地运行 i3 的 Ubuntu 18.04 上对我有用的唯一答案。无需 X11 转发。【参考方案7】: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 -- 非常简洁。但是——当我这样做时,cat some_useful_content.txt | nc localhost 2000
命令似乎挂起。我需要手动 ctr-c 来停止它,只有这样内容才能到达我的客户端剪辑/粘贴板
它会等到有人将另一端的数据出列。
其实我想我误解了你的问题。我不知道为什么会这样。
nc -l -p
对我有用,但只是 nc -l
不行。我也有@AlanStorm 的问题。
我通过指定-c
解决了挂网猫的问题。我使用 brew 安装的 GNU netcat。【参考方案8】:
最简单的解决方案,如果您在 OS X 上使用终端,并且您一直在远程服务器中进行 ssh,并希望获取文本文件、日志或 csv 的结果,只需:
1)Cmd-K
清除终端输出
2)cat <filename>
显示文件内容
3) Cmd-S
保存终端输出
您将手动删除文件的第一行和最后一行,但这种方法比依赖安装其他软件包、“反向隧道”和尝试拥有静态 IP 等要简单一些。
【讨论】:
+1 是我自己使用过的一种有用技术,它确实会迫使您丢失终端历史记录,并且(如前所述)第一行/最后一行问题有点繁琐。 同意@AlanStorm 这种方法更重要的问题是它只会保存终端缓冲区保留的行数。通常这不是问题,但是如果您尝试获取日志文件的内容,那么您可能会耗尽容量, 这是真的@Sridhar-Sarnobat,一般来说这不是一个很好的解决方案。我只是使用scp
!
将步骤 3 替换为 Cmd-A
(全选)和 Cmd-C
以复制到剪贴板。起初,我认为Cmd-A
只会选择可见屏幕的文本,但它确实会选择全部。【参考方案9】:
我最喜欢的方式是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
【讨论】:
+1:当无法进行反向 SSH 连接时,比其他解决方案容易得多! 这个极其简单的解决方案,你应该得到更多的赞! 对于我们这些使用 Mac OSX 的人,ssh [remote-machine] "cat log.txt" | pbcopy
根据这份报告here,我必须使用cat
才能使其在cygwin Windows 8 上运行:ssh [remote-machine] "cat log.txt" | cat > /dev/clipboard
(当然,我的远程命令不是cat
;这是流浪虚拟机中的其他东西,所以我实际上运行了vagrant ssh -c "command" | cat > /dev/clipboard
)
几乎总是可以使用 SSH 端口转发设置反向 ssh 连接。只需将RemoteForward 127.0.0.1:2222 127.0.0.1:22
添加到本地.ssh/config
中的服务器条目,然后在远程机器上执行ssh -p 2222 127.0.0.1
,然后将连接重定向到本地机器。【参考方案10】:
不是单行,但不需要额外的 ssh。
必要时安装netcat
使用termbin:cat ~/some_file.txt | nc termbin.com 9999
。这会将输出复制到 termbin
网站并将 URL 打印到您的输出中。
从您的计算机访问该 url,您将获得输出
当然,请勿将其用于敏感内容。
【讨论】:
哇,这是一个非常有创意的解决方案。【参考方案11】:这是我基于 SSH 反向隧道、netcat 和 xclip 的解决方案。
首先在您的工作站上创建脚本(例如,clipboard-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
然后尝试在您的工作站上粘贴
您当然可以编写包装脚本,先启动 clipboard-daemon.sh,然后再启动 ssh 会话。这就是它对我有用的方式。享受吧。
【讨论】:
这个解决方案是最适合我的。它不是太复杂并且可以正常工作。 我认为最好的解决方案。您不必担心允许存在安全隐患的反向 ssh 连接,并且无限循环是一个不错的选择。【参考方案12】:@rhileighalmgren 解决方案很好,但是 pbcopy 会烦人地复制最后一个“\n”字符,我使用“head”去掉最后一个字符以防止这种情况:
#!/bin/bash
head -c -1 | ssh desktop pbcopy
我的完整解决方案在这里:http://taylor.woodstitch.com/linux/copy-local-clipboard-remote-ssh-server/
【讨论】:
pbcopy
并不是要对它复制的内容做出判断,所以它包含你给它的一切是有道理的。【参考方案13】:
找到了一个不需要反向 ssh 连接的绝佳解决方案!
您可以在远程主机上使用 xclip,以及在 OSX 系统上使用 ssh X11 转发和 XQuartz。
设置:
-
安装 XQuartz(我使用 soloist + pivotal_workstation::xquartz recipe 完成了此操作,但您不必这样做)
运行 XQuartz.app
打开 XQuartz 首选项 (+
,
)
确保选中“启用同步”和“当剪贴板更改时更新粘贴板”
ssh -X remote-host "echo 'hello from remote-host' | xclip -selection clipboard"
【讨论】:
这与ssh remote-host "echo 'hello from remote-host' | pbcopy
有何不同?如果它可以像这样工作,这将是一个很好的答案:ssh -X remote-host
然后在远程主机上:echo 'hello from remote-host' | xclip -selection clipboard
@KasperSouren。我相信它确实如你所愿。 ` | xclip` 在双引号内。
在 2016 年,这显然是最好的、简洁的解决方案。忘记其他基于反向 ssh 的解决方案。
有没有办法做到这一点,而它只是一个一次性命令?我想通过 ssh 在交互式会话中登录到我的远程服务器,然后能够任意发送到我的本地剪贴板。这需要反向 ssh 吗?
@Kvass:只要您使用-X
通过 SSH 进行 X11 转发,X11 程序就可以通过上面的 XQuartz 设置更新您的剪贴板。一次性命令是为了证明通过echo
通过xclip
向远程主机的剪贴板发送内容确实有效并且应该同步到您的本地SSH 客户端主机。注意@gdw2 说,“| xclip
在双引号内”。因此,它将作为远程服务器上的命令执行以向其剪贴板发送内容。【参考方案14】:
我正在复活这个帖子,因为我一直在寻找相同的解决方案,并且我找到了一个适合我的解决方案。这是对OSX Daily 的建议的小修改。
就我而言,我使用本地 OSX 机器上的终端通过 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 保存它(我的助记符(剪贴板)。将脚本放在路径中的某个位置,使其可执行并瞧:
ls | cb
【讨论】:
我在vim中经常这样。为此,请在可视模式下选择要复制的内容,然后键入::'<,'>w !ssh desktop pbcopy
@MikeBrennan 选择文本后,为什么不直接按 cmd+C(或您设置的任何复制键)? ...
像这样,只有当您的桌面具有静态 IP 并且可以从您 ssh 进入的盒子中访问时,它才真正起作用。对我来说从来不是这样。
反过来不是更容易吗? ssh user@remote 'commandThatMakesOutput' |pbcopy
我需要这里描述的-e none
ssh 标志:unix.stackexchange.com/questions/210615/…【参考方案15】:
有多种工具可以访问 X11 选项,包括 xclip 和 XSel。请注意,X11 传统上具有多个选择,并且大多数程序对剪贴板和主选择都有一定的了解(它们并不相同)。 Emacs 也可以使用辅助选择,但这种情况很少见,而且没有人真正知道如何处理剪切缓冲区...
$ xclip -帮助 用法:xclip [选项] [文件] ... 访问 X 服务器选择以进行读取或写入。 -i, -in 从标准输入或文件中将文本读入 X 选择 (默认) -o, -out 将选择打印到标准输出(通常用于 管道到文件或程序) -l, -loops 退出前等待的选择请求数 -d, -display X 显示连接到(例如 localhost:0") -h, -help 使用信息 -选择访问(“主要”,“次要”,“剪贴板”或“缓冲剪切”) -noutf8 不要将文本视为 utf-8,使用旧的 unicode -version 版本信息 - 仅无提示错误,在后台运行(默认) - 在前台安静运行,显示正在发生的事情 -详细的运行评论 向 报告错误 $ 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 对剪贴板选择进行操作 -k, --keep 不修改选择,但使 PRIMARY 和 SECONDARY 选择仍然存在,即使在 他们在退出时选择的程序。 -x, --exchange 交换 PRIMARY 和 SECONDARY 选择 X 选项 --显示显示名称 指定到 X 服务器的连接 -t 毫秒,--selectionTimeout 毫秒 以毫秒为单位指定超时,在该时间内 必须检索选择。值 0(零) 指定无超时(默认) 其他选项 -l, --logfile 指定分离时记录错误的文件。 -n, --nodetach 不要从控制终端分离。没有 这个选项,xsel会fork成为背景 在输入、交换和保存模式中处理。 -h, --help 显示此帮助并退出 -v, --verbose 打印信息性消息 --version 输出版本信息并退出 请向简而言之,您应该尝试xclip -i
/xclip -o
或xclip -i -sel clip
/xclip -o -sel clip
或xsel -i
/xsel -o
或xsel -i -b
/xsel -o -b
,这取决于您想要什么。
【讨论】:
添加到@ephemient 的帖子:为了在远程主机上使用xclip 和xsel,您可以像这样使用X11 转发:ssh -C -X user@remote-host
。如果在远程端运行 xclip 似乎不起作用,请确保在远程 /etc/ssh/sshd_config
文件中设置了 X11Forwarding yes
。还要确保xauth
安装在远程端。对于无头机器,可以安装xauth
和xvfb
。
这是一个description,包含额外的细节以及 vim 键绑定。
@TrinitronX 哦哇——我的头撞到墙上了,感谢xvfb
的提及。我正在运行一个无头服务器,所以 X11 一定没有运行!以上是关于如何从远程 SSH 会话将数据发送到本地剪贴板的主要内容,如果未能解决你的问题,请参考以下文章
如何在远程 Linux ssh 会话上运行的 vim 中拉到本地 OSX 剪贴板?
当我通过 Git Bash 中的 ssh 在远程 Linux 机器上运行命令时,如何将文件的内容直接复制到我的 Windows 剪贴板中?