繁体   English   中英

在 Bash 脚本中使用 Expect 为 SSH 命令提供密码

[英]Use Expect in a Bash script to provide a password to an SSH command

我正在尝试在 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 密钥的人,请弃权。

混合使用 Bash 和 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 ,然后返回(片刻)交互式会话。

最简单的方法是使用sshpass 这在Ubuntu / Debian存储库中可用,您不必处理与 Bash 集成的期望。

一个例子:

sshpass -p<password> ssh <arguments>
sshpass -ptest1324 ssh user@192.168.1.200 ls -l /tmp

上面的命令可以很容易地与 Bash 脚本集成。

注意:请阅读man sshpass安全注意事项部分以全面了解安全隐患。

在 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。

在为这个问题寻找了几个月的答案后,我终于找到了一个真正最好的解决方案:编写一个简单的脚本。

#!/usr/bin/expect

set timeout 20

set cmd [lrange $argv 1 end]
set password [lindex $argv 0]

eval spawn $cmd
expect "assword:"   # matches both 'Password' and 'password'
send "$password\r";
interact

把它放到/usr/bin/exp ,然后你可以使用:

  • exp <password> ssh <anything>
  • exp <password> scp <anysrc> <anydst>

完毕!

一个简单的 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>

还要确保使用

send -- "$PWD\r"

相反,因为以破折号 (-) 开头的密码将失败。

以上不会将以破折号开头的字符串解释为发送命令的选项。

使用辅助工具fd0ssh (来自 hxtools,而不是 pmt)。 它无需期待来自ssh程序的特定提示即可工作。

我发现使用 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...

如果您尝试在Sublime Text构建目标中,在 Makefile 中使用它, sshpass被破坏。 取而代之的sshpass ,您可以使用passhhttps://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

参考:

  1. 在 SSH 连接中使用 Expect 脚本发送密码命令不起作用
  2. 如何在 ssh 中禁用严格的主机密钥检查?
  3. 如何禁用 SSH 主机密钥检查
  4. scp 没有 known_hosts 检查
  5. 带密码认证的 pam_mount 和 sshfs

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM