通过 SSH 运行 shell 时如何自动输入?

Posted

技术标签:

【中文标题】通过 SSH 运行 shell 时如何自动输入?【英文标题】:How to input automatically when running a shell over SSH? 【发布时间】:2012-02-22 22:22:26 【问题描述】:

在我的 shell 脚本中,我正在运行一个要求我输入的命令。

如何自动为命令提供所需的输入?

例如:

$cat test.sh
ssh-copy-id tester@10.1.2.3

运行 test.sh 时:

首先,它会问:

Are you sure you want to continue connecting (yes/no)?

然后,它会要求我输入密码:

tester@10.1.2.3's password:

有没有办法自动输入?

【问题讨论】:

【参考方案1】:

对于简单的输入,例如两个提示和两个对应的固定响应,您还可以使用“这里文档”,其语法如下所示:

test.sh <<!
y
pasword
!

【讨论】:

我收回来,ssh 通过 tty 设备提示,它绕过了标准输入。用 Emily Litella 的话来说,“没关系”。 :) 唉!在浪费了几个小时之后......找到了最好的解决方案,谢谢。 标题未指定 SSH,因此虽然这不适用于 OP,但发现问题的其他人可能需要并使用此答案。顺便说一句,这里的字符串语法——&lt;&lt;&lt;$'y\npasword'——也可能对其他人有用。【参考方案2】:

对于一般的命令行自动化,Expect 是经典工具。或者,如果您更熟悉 Python,请尝试 pexpect。

这里有一个类似的问题,建议使用 Expect:Use expect in bash script to provide password to SSH command

【讨论】:

我们真的应该停止宣传 expect 作为一种自动化 ssh 的方式。 SSH 故意使这些提示难以自动化,以促使我们使用正确的解决方案:命令行标志绕过确认和公钥/私钥消除密码提示。 这很理想,但现实世界往往并不理想。对于提出的问题,这是典型的方法。如果您使用密钥,您可能也需要密钥上的密码,然后您很可能处于相同的情况。当然,您可以ssh-agentkeychain 等,但有时会有不方便或不切实际的原因。【参考方案3】:

肯定有……使用 spawn、expect 和 send 命令:

spawn test.sh
expect "Are you sure you want to continue connecting (yes/no)?"
send "yes"

Stack Overflow 上还有更多示例,请参阅: Help with Expect within a bash script

您可能需要先安装这些命令,具体取决于您的系统。

【讨论】:

我们真的应该停止宣传 expect 作为自动化 ssh 的一种方式。 SSH 故意使这些提示难以自动化,以促使我们使用正确的解决方案:命令行标志绕过确认和公钥/私钥消除密码提示。 如果是第 3 方脚本,并且命令行标志不可用怎么办? @HarshVerma 答案没有警告或警告,所以我坚持我的评论。【参考方案4】:

ssh-key with passphrase, with keychain

keychain 是一个小型实用程序,它代表您管理 ssh-agent 并允许 ssh-agent 在登录会话结束时保持运行。在后续登录时,钥匙串将连接到现有的 ssh-agent 实例。实际上,这意味着密码只能在重新启动后的第一次登录时输入。在后续登录时,将使用来自现有 ssh-agent 实例的未加密密钥。这对于在没有无密码 ssh 密钥的 cron 作业中允许无密码 RSA/DSA 身份验证也很有用。

要启用钥匙串,请安装它并将以下内容添加到 ~/.bash_profile:

评估keychain --agents ssh --eval id_rsa 从安全的角度来看,ssh-ident 和 keychain 不如 ssh-agent 实例受限于特定会话的生命周期,但它们提供了高度的便利性。为了提高钥匙串的安全性,有些人在他们的 ~/.bash_profile 钥匙串调用中添加了 --clear 选项。通过这样做,必须如上所述在登录时重新输入密码,但 cron 作业在用户注销后仍然可以访问未加密的密钥。钥匙串 wiki 页面有更多信息和示例。

此信息来自;

https://unix.stackexchange.com/questions/90853/how-can-i-run-ssh-add-automatically-without-password-prompt

希望对你有帮助

我个人可以通过执行以下操作在终端启动时自动输入我的密码:(当然,您可以修改脚本并使其适合您的需要)

    编辑 bashrc 文件以添加此脚本;

    检查 SSH 代理是否处于唤醒状态

    如果 [ -z "$SSH_AUTH_SOCK" ] ;然后 exec ssh-agent bash -c "ssh-add ; $0" echo "SSH 代理被唤醒" 出口 菲

    上面的行将在终端启动时启动期望脚本。

    ./ssh.exp

这是这个期望脚本的内容

#!/usr/bin/expect

set timeout 20

set passphrase "test"

spawn "./keyadding.sh"

expect "Enter passphrase for /the/path/of/yourkey_id_rsa:"

send "$passphrase\r";

interact

这是我的 keyadding.sh 脚本的内容(您必须将两个脚本都放在您的主文件夹中,通常是 /home/user)

#!/bin/bash

ssh-add /the/path/of/yourkey_id_rsa

exit 0

我强烈建议对 .exp 脚本上的密码进行加密,并将此 .exp 文件重命名为 term_boot.exp 或其他任何内容以确保安全。不要忘记创建使用 nano 或 vim 直接从终端(例如:nano ~/.bashrc | nano term_boot.exp)以及chmod +x script.sh 使其可执行文件。 chmod +r term_boot.exp 也很有用,但您必须在 bashrc 文件中的 ./ssh.exp 之前添加 sudo。因此,每次启动终端时都必须输入 sudo 密码。对我来说,它比密码更方便,因为我记得我的管理员(sudo)密码。

另外,我认为还有另一种方法; https://www.cyberciti.biz/faq/noninteractive-shell-script-ssh-password-provider/

如果我有时间,肯定会改变我的方法。

【讨论】:

【参考方案5】:

您还可以将答案传递给脚本:

printf "y\npassword\n" | sh test.sh

\n 是转义序列

【讨论】:

以上是关于通过 SSH 运行 shell 时如何自动输入?的主要内容,如果未能解决你的问题,请参考以下文章

Linux shell中自动完成登录

使用expect实现自动交互,shell命令行自动输入

如何在shell脚本中自动输入密码?

shell脚本中ssh到远程机子时,提示输入密码?用变量给出密码 要怎么做?请各位帮忙

Linux shell脚本如何自动运行程序并输入命令

如何自动输入密码ssh连接到其他机器