在 Bash 脚本中使用 Expect 为 SSH 命令提供密码
我尝试在 Bash 脚本中使用 expect
来提供 SSH 密码。提供密码是可行的,但我并没有像我应该的那样进入 SSH 会话。它又回到了 Bash。
我的脚本:
#!/bin/bash
read -s PWD
/usr/bin/expect <<EOD
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com'
expect "password"
send "$PWD\n"
EOD
echo "you're out"
我的脚本的输出:
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com
usr@$myhost.example.com's password: you're out
我想要进行 SSH 会话,并且只有当我退出它时,才返回到我的 Bash 脚本。
我之所以在 expect
之前使用 Bash 是因为我必须使用菜单。我可以选择连接到哪个单元/设备。
对于那些想回复我应该使用 SSH 密钥的人,请弃权。
I'm trying to use expect
in a Bash script to provide the SSH password. Providing the password works, but I don't end up in the SSH session as I should. It goes back strait to Bash.
My script:
#!/bin/bash
read -s PWD
/usr/bin/expect <<EOD
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com'
expect "password"
send "$PWD\n"
EOD
echo "you're out"
The output of my script:
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com
usr@$myhost.example.com's password: you're out
I would like to have my SSH session and, only when I exit it, to go back to my Bash script.
The reason why I am using Bash before expect
is because I have to use a menu. I can choose which unit/device to connect to.
To those who want to reply that I should use SSH keys, please abstain.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
混合使用 Bash 和 Expect 并不是达到预期效果的好方法。我尝试仅使用 Expect:
bash 的示例解决方案可能是:
这将等待 Enter,然后返回(暂时)交互式会话。
Mixing Bash and Expect is not a good way to achieve the desired effect. I'd try to use only Expect:
Sample solution for bash could be:
This will wait for Enter and then return to (for a moment) the interactive session.
最简单的方法是使用sshpass。这在 Ubuntu/Debian 存储库,您不必处理将 Expect 与 Bash 集成的问题。
示例:
上面的命令可以轻松地与 Bash 脚本集成。
注意:请阅读
man sshpass
中的安全注意事项部分,以全面了解安全影响。The easiest way is to use sshpass. This is available in Ubuntu/Debian repositories and you don't have to deal with integrating expect with Bash.
An example:
The above command can be easily integrated with a Bash script.
Note: Please read the Security Considerations section in
man sshpass
for a full understanding of the security implications.在 EOD 之前添加“interact”Expect 命令:
这应该允许您与远程计算机交互,直到您注销。然后您将返回 Bash。
Add the 'interact' Expect command just before your EOD:
This should let you interact with the remote machine until you log out. Then you'll be back in Bash.
在寻找这个问题的答案几个月后,我终于找到了一个真正最好的解决方案:编写一个简单的脚本。
将其放入
/usr/bin/exp
中,然后您可以使用:exp; ssh <任何东西>
exp <密码> scp;
完成!
After looking for an answer for the question for months, I finally find a really best solution: writing a simple script.
Put it to
/usr/bin/exp
, then you can use:exp <password> ssh <anything>
exp <password> scp <anysrc> <anydst>
Done!
一个简单的 Expect 脚本:
文件 Remotelogin.exp
示例:
A simple Expect script:
File Remotelogin.exp
Example:
还要确保使用
相反的方式,否则以破折号 (-) 开头的密码将会失败。
上面不会将以破折号开头的字符串解释为发送命令的选项。
Also make sure to use
instead, as passwords starting with a dash (-) will fail otherwise.
The above won't interpret a string starting with a dash as an option to the send command.
使用帮助工具
fd0ssh
(来自 hxtools,ubuntu 源,openSUSE 源,不是 pmt)。它的工作不需要ssh
程序的特定提示。它还“比像 sshpass 那样在命令行上传递密码安全得多”(- Charles Duffy 的评论)。
Use the helper tool
fd0ssh
(from hxtools, source for ubuntu, source for openSUSE, not pmt). It works without having to expect a particular prompt from thessh
program.It is also "much safer than passing the password on the command line as sshpass does" ( - comment by Charles Duffy).
我发现从 Bash 脚本使用小型 Expect 脚本很有用的另一种方法如下。
这是有效的,因为
...如果提供字符串“-”作为文件名,则会读取标准输入...
Another way that I found useful to use a small Expect script from a Bash script is as follows.
This works because
...If the string "-" is supplied as a filename, standard input is read instead...
如果您尝试在 Sublime Text 中使用
sshpass
,它就会被破坏构建目标,在 Makefile 中。 您可以使用passh
,而不是sshpass
使用
sshpass
,您将执行以下操作:使用
passh
,您将执行以下操作:注意:不要忘记使用
-o StrictHostKeyChecking=no
。否则,连接将在您第一次使用时挂起。例如:参考文献:
sshpass
is broken if you try to use it inside a Sublime Text build target, inside a Makefile. Instead ofsshpass
, you can usepassh
With
sshpass
you would do:With
passh
you would do:Note: Do not forget to use
-o StrictHostKeyChecking=no
. Otherwise, the connection will hang on the first time you use it. For example:References: