为什么“scp”不打印由authorized_keys文件(或任何其他启动脚本)的“command”指令指定的脚本的所有输出

为什么“scp”不打印由authorized_keys文件(或任何其他启动脚本)的“command”指令指定的脚本的所有输出

我需要一个 bash 脚本,在对服务器执行ssh或命令时自动启动。我这样做:scpsshscp

ssh -i path/to/key me@server some_command

或者

scp -i path/to/key file_to_copy me@server:/destination_folder

我的脚本应该检测启动了什么命令(sshscp),然后如果需要则解析参数(在此示例中为some_command)。

为了使该脚本自动启动,我在中添加了一个命令authorized_keys,如下所示:

command="~/script",no-pty,no-x11-forwarding,no-agent-forwarding ssh-rsa ...

好的,现在假设script是:

#!/usr/bin/env bash

echo "hello"
echo "hello1"
echo "hello2"

好了,这样做之后ssh -i path/to/key me@server some_command,我看到我的 shell(“客户端”)上打印了“hello”、“hello1”、“hello2”。完美。

当这样做的时候scp -i path/to/key file_to_copy me@server:/destination_folder,我只看到我的 shell (客户端)上打印了“hello”。

为什么?我该如何避免这种情况?请注意,如果echo我对某个cat文件执行一些操作而不是执行一些操作,那么在命令的情况下scp,它只会打印第一行!(并且该ssh命令再次运行良好并打印所有行)。

多谢!

答案1

SSH 命令的标准输出并不总是您的终端。

scp、rsync 或 git 等工具实际上几乎完全通过 stdin/stdout 与服务器端组件进行通信 - 并且它们希望接收符合其自身协议的消息,而不仅仅是随机的 ASCII 文本。

因此,当本地scp客户端在发送请求之前收到任何文本时,它会将其视为协议违规。它会打印第一行只是为了友善,但随后退出,因为它无法与远程 scp 处理程序通信,并且向用户传递消息不是其功能的一部分。

其他工具根本不会打印任何文本。例如,rsync 只会报告错误:

$ rsync badserver:test.c /tmp
protocol version mismatch -- is your shell clean?
rsync error: protocol incompatibility (code 2) at compat.c(178) [Receiver=3.1.3]

Git 和其他使用 SSH 作为传输方式的工具也是如此:它们希望完全控制 stdin 和 stdout,就像使用 TCP 连接一样。(有些客户端确实会传递写入标准错误使用>&2,但大多数不会;OpenSSH scp 不会,PuTTY pscp 也不会。)

没有完全通用的方法可以通过 shellscript 显示任意消息。但是如果你只需要一个基本的问候语,你可以显示静止的使用 sshdBanner选项的消息 – 例如 OpenSSH 服务器可以根据用户名、组、IP 地址和 支持的其它条件提供不同的消息Match。SSH 客户端将识别横幅消息,将其与正常的 stdout/stderr 区分开来。

答案2

您无法打印任何事物在使用 SCP 或 SFTP 等严格协议的会话中。这样做会破坏协议。使用scp(OpenSSH 命令行 SCP 客户端),如果您将输出打印到 stderr,它可能会起作用。但您可能会破坏其他 SCP 客户端(例如我的 WinSCP)。

改用 SSH 横幅。

有关类似主题,请参阅:


但是你真的希望命令在客户端打印任何内容吗?你不只是想调试/测试你的脚本吗?你考虑过将输出写入服务器上的文件中吗?

相关内容