我的脚本:
#!/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密钥的人,请弃权。
#1 楼
混合Bash和Expect不是达到预期效果的好方法。我只尝试使用Expect:#!/usr/bin/expect
eval spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com
# Use the correct prompt
set prompt ":|#|\$"
interact -o -nobuffer -re $prompt return
send "my_password\r"
interact -o -nobuffer -re $prompt return
send "my_command1\r"
interact -o -nobuffer -re $prompt return
send "my_command2\r"
interact
bash的示例解决方案可能是:
#!/bin/bash
/usr/bin/expect -c 'expect "\n" { eval spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com; interact }'
这将等待Enter,然后返回(片刻)交互式会议。
评论
很好,谢谢。如果我想通过SSH登录后键入命令,该怎么办?
–最大
2011年1月25日13:28
该脚本应返回具有已登录用户的无效外壳程序。我不明白问题。如果您绝对要在bash中使用相同的脚本,请查看已编辑的条目。
–彼得·克罗尔(PiotrKról)
2011-1-25 13:49
与提示时发送密码的方式相同,登录后我想发送系统命令。
–最大
2011年1月26日14:43
上面已添加了Samlple代码。当然,这将一直有效,直到my_commandX不更改返回的提示为止,如果发生这种情况,则应该更改提示变量。
–彼得·克罗尔(PiotrKról)
2011-1-26 15:37
@pietrushnic您能否解释一下为什么使用“ interact -o -nobuffer -re $ prompt return”而不是“ expect $ prompt”?后者看起来更常用。
–理查德
2012年9月20日11:12
#2 楼
最简单的方法是使用sshpass。这在Ubuntu / Debian存储库中可用,您不必处理将期望与Bash集成的情况。示例:
sshpass -p<password> ssh <arguments>
sshpass -ptest1324 ssh user@192.168.1.200 ls -l /tmp
上述命令可以轻松地与Bash脚本集成。
注意:请阅读
man sshpass
中的“安全注意事项”部分,以全面了解安全隐患。评论
我不知道这是否是一个好的解决方案,但是它确实简化了很多。谢谢
–erikbwork
15年2月10日在18:52
从安全角度来看非常危险-命令行参数可由系统上的任何其他进程读取。可能会覆盖它们,希望sshpass可以这样做,但是即使有一段时间,它仍然可以启动,直到任何/每个进程都可以看到密码时才可以这样做。
–查尔斯·达菲(Charles Duffy)
15年5月21日在22:45
@CharlesDuffy当然,您是正确的。 sshpass用于具有简单测试脚本的情况,这些脚本在安全不是重点的本地网络环境中执行。实际上,man sshpass中有一个部分说明了有关安全注意事项的整个部分。添加此答案,谢谢。
– dotnix
15年5月22日在17:16
@ erikb85通常,程序包会为您完成所有肮脏的工作,但在所有情况下,这些脚本都是专门为该用途而构建的,因此比添加您自己的工作更好。此评论是关于不要重新发明轮子。仅当没有人处理过硬质物品时,才进行处理。 sshpass这是一个很好的功能。
– m3nda
2015年6月5日19:36
为了完整起见,我提到“ man sshpass”会向潜在用户提供适当的安全警告,并指出“ -p”是使用它的最不安全的方式,并提供了“ -e”选项以通过环境变量获取密码,至少可以使它脱离命令行。
–罗恩·伯克(Ron Burk)
16年4月14日在16:27
#3 楼
在EOD之前添加'interact'Expect命令:#!/bin/bash
read -s PWD
/usr/bin/expect <<EOD
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com
expect "password"
send "$PWD\n"
interact
EOD
echo "you're out"
这将使您与远程计算机进行交互,直到注销为止。然后您将回到Bash。
评论
它进入并立即退出。印有“你不在”的字样。
–伊曼纽尔
2013年4月30日14:03在
我已将“ interact”和“ EOD”替换为“ expect eof”,它对我有用。这是在Mac上。
–伊曼纽尔
13年4月30日在14:08
此页面上的答案均不适合我,但@Emmanuel的建议使用Expect eof解决了该问题。
– moertel
17-10-9在12:21
从usr@$myhost.example.com中删除“,它应该可以工作。也许您需要将\ n替换为\ r,但是YMMV
– Tino
18年6月12日在18:32
#4 楼
在寻找了几个月的问题答案之后,我终于找到了一个真正最佳的解决方案:编写一个简单的脚本。#!/usr/bin/expect
set timeout 20
set cmd [lrange $argv 1 end]
set password [lindex $argv 0]
eval spawn $cmd
expect "Password:"
send "$password\r";
interact
将其放入
/usr/bin/exp
,然后可以使用:exp <password> ssh <anything>
exp <password> scp <anysrc> <anydst>
完成!
评论
期望“密码:”是指期望“密码:”吗?
–用户
19年4月28日在7:45
@user“ assword”将同时匹配密码和密码。
– Ferdinand.kraft
19年4月4日在0:36
带有两个参数的scp也很棒。当然,ssh也可以有2个参数。
– Timo
11月7日19:37
#5 楼
另外,请务必使用send -- "$PWD\r"
,否则以破折号(-)开头的密码将会失败。
以上内容不会将以破折号开头的字符串解释为发送命令。
#6 楼
一个简单的Expect脚本:文件Remotelogin.exp
#!/usr/bin/expect
set user [lindex $argv 1]
set ip [lindex $argv 0]
set password [lindex $argv 2]
spawn ssh $user@$ip
expect "password"
send "$password\r"
interact
示例:
./Remotelogin.exp <ip> <user name> <password>
#7 楼
使用辅助工具fd0ssh
(来自hxtools,而非pmt)。它可以正常工作,而无需期待来自ssh
程序的特定提示。评论
这很棒!要使其运行起来有点困难(至少在ubuntu服务器中),但可以正常运行!我们进行的配置:echo“ yoursshpass” | fd0ssh ssh -c -L $ port:$ ip:$ remote_port user@yourserver.com&谢谢!
– JP Illanes
2011年11月2日23:54
与sshpass相比,比在命令行上传递密码安全得多。
–查尔斯·达菲(Charles Duffy)
15年5月21日在22:46
#8 楼
我发现使用Bash脚本中的小Expect脚本有用的另一种方法如下。 ...
Bash script start
Bash commands
...
expect - <<EOF
spawn your-command-here
expect "some-pattern"
send "some-command"
...
...
EOF
...
More Bash commands
...
之所以有效,是因为
...If the string "-" is supplied as a filename, standard input is read instead...
评论
您不需要-这里,因为如果您不带参数调用它,则默认情况下,它会从stdin中读取期望值。但是,如果您希望在不使用命令提示符的情况下以交互方式运行它(期望与期望-),或者在执行期望-f“ $ @”之类的操作时,即使第一个参数看起来像一个文件,它也很有用,选项(以-开头)。在这种情况下,如果$ 1(给定的文件)为-这将从stdin中读取。
– Tino
18年6月12日在18:29
#9 楼
如果您尝试在Makefile的Sublime Text构建目标中使用它,则会损坏sshpass
。代替sshpass
,可以使用passh
:https://github.com/clarkwang/passh 使用
sshpass
可以做到:sshpass -p pa$$word ssh user@host
使用
passh
可以做到:passh -p pa$$word ssh user@host
注意:不要忘记使用
-o StrictHostKeyChecking=no
。否则,连接将在您第一次使用时挂起。例如:passh -p pa$$word ssh -o StrictHostKeyChecking=no user@host
参考文献:
在SSH连接中使用Expect脚本发送密码的命令不起作用
如何在ssh中禁用严格的主机密钥检查?
如何禁用SSH主机密钥检查
scp,而无需known_hosts检查
通过密码认证的pam_mount和sshfs
评论
请参阅第一行:对于那些想回复我应该使用SSH密钥的人,请弃权我会编辑您的第一行,使其更加友好。您可能会考虑类似“由于约束,我根本无法使用SSH密钥,我必须找到一种使其与Expect配合使用的方法”之类的东西。您应该期望人们会自然地好奇您为什么不使用键,而只是想提供帮助:) @Ignacio并不建议您使用键,他只是在确认它是一个约束而不是疏忽。
在这种情况下,我会尝试使用kermit。它具有非常强大的脚本语言columbia.edu/kermit/skermit.html#scripts