我正在开发一个简单的脚本,它连接到某些计算机并通过ssh
会话执行某些命令:
sshpass -p 'password' ssh $target_ip << EOF
echo \$PATH
# example
echo \$HOSTNAME
[...]
EOF
该操作是正确的,但令我困扰的是,在每个连接上它都会显示ssh
服务器横幅并干扰脚本的其余部分stdout
:
Welcome to Ubuntu 20.04.2 LTS (GNU/Linux 5.4.0-81-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Wed Nov 23 11:58:14 CET 2022
System load: 0.44 Processes: 131
Usage of /: 9.2% of 108.79GB Users logged in: 0
Memory usage: 26% IPv4 address for br0: 172.16.20.11
Swap usage: 0% IPv4 address for br0: 10.130.1.1
Temperature: 36.0 C IPv4 address for tun0: 10.130.0.27
* Strictly confined Kubernetes makes edge and IoT secure. Learn how MicroK8s
just raised the bar for easy, resilient and secure K8s cluster deployment.
https://ubuntu.com/engage/secure-kubernetes-at-the-edge
241 updates can be installed immediately.
134 of these updates are security updates.
To see these additional updates run: apt list --upgradable
The list of available updates is more than a week old.
To check for new updates run: sudo apt update
New release '22.04.1 LTS' available.
Run 'do-release-upgrade' to upgrade to it.
因此,我不希望显示该横幅并且仅有的我在EOF
.
以防万一它是相关的,我使用的 SSH 版本是OpenSSH_9.1p1, OpenSSL 3.0.7 1 Nov 2022
.对于服务器来说,它是OpenSSH_8.2p1 Ubuntu-4ubuntu0.3, OpenSSL 1.1.1f 31 Mar 2020
。
我不想从服务器中删除横幅,这可以在sshd
配置中完成。我想要的是客户端在脚本中禁用横幅打印。
然而,对其他人有用的 ssh 线路选项(我一直在这里和这里)没有为我工作:
ssh -o LogLevel=error $ip
还:
ssh -q $ip
如何在客户端级别禁用此功能?是否没有 ssh 选项或参数可以让我执行此操作?如果没有,我如何将其重定向stdout
到/dev/null
而不触及我在 中执行的命令的输出EOF
?
答案1
SSH 身份验证前的横幅来自SSH 服务器的Banner
选项。sshd_config
如果不更改服务器的配置,您无法使服务器不将其发送给您。您的客户端应该将其打印到 stderr,因此2>/dev/null
会在本地抑制它,但它也会抑制其他消息ssh
(sshpass
在您的情况下)打印到 stderr。
SSH 身份验证后的横幅很可能来自远程 shell 的某些启动脚本。*如果ssh "$target_ip" date
显示这样的横幅,那么您应该检查服务器上的启动脚本,找到负责打印横幅的代码并修复它。如果罪魁祸首位于某个全局脚本(在/etc
)中,则创建相应的私有脚本(在您的$HOME
)中可能允许您更改行为。请参阅服务器上登录 shell 的文档。
如果ssh "$target_ip" date
不显示横幅,则意味着当前相关脚本禁止非交互式 shell 的横幅。您可以利用这一事实使横幅静音,而无需更改服务器上的任何内容。
您sshpass -p 'password' ssh $target_ip << EOF
不会将任何初始命令传递到远程端,因此 SSH 服务器会为您启动一个交互式 shell,读取其标准输入,然后才会使用此处的文档。
要启动非交互式 shell,请传递命令。它应该是您想要使用的 shell,并且您应该确保它不会以交互方式启动。最好不要依赖$SHELL
或任何东西的远程值,因为您在本地知道您的此处文档用于什么 shell。不再需要原来的远程 shell,因此这exec
是一个好主意。
在下面的示例中,请求的 shell 是bash
.它不会以交互方式启动,因为它的标准输入不是 tty(作为比较:导致问题的远程 shell 会以交互方式启动,而与 tty 无关,因为 SSH 服务器明确请求了这一点)。
sshpass -p 'password' ssh "$target_ip" 'exec bash' << EOF
echo \$PATH
# example
echo \$HOSTNAME
[...]
EOF
* 一般来说,服务器上的正式默认 shell 可以是任何东西,例如,bash
独立于启动脚本无条件打印某些内容的包装器,然后运行bash
。这是一个奇异的场景,但也是可能的。最有可能的事实并非如此。