bash - 在 Bash 脚本中嵌入 Expect 脚本

标签 bash expect

我有以下脚本:

#!/bin/bash

if [ `hostname` = 'EXAMPLE' ]
then

/usr/bin/expect << EOD

spawn scp -rp host:~/outfiles/ /home/USERNAME/outfiles/
expect "id_rsa':"
send "PASSWORD\r"
interact

spawn scp -rp host:~/errfiles/ /home/USERNAME/errfiles/
expect "id_rsa':"
send "PASSWORD\r"
interact

expect eof

EOD

echo 'Successful download'
fi

不幸的是,它似乎不起作用,我收到一条错误消息:

spawn scp -rp host:~/outfiles/ /home/USERNAME/outfiles/
Enter passphrase for key '/home/USERNAME/.ssh/id_rsa': interact: spawn id exp0 not open
    while executing
"interact"

我不知道它是什么意思,也不知道为什么它不起作用。但是,当我使用非嵌入式 Expect 脚本编写上述代码时:

#!/usr/bin/expect

spawn scp -rp host:~/outfiles/ /home/USERNAME/outfiles/
expect "id_rsa':"
send "PASSWORD\r"
interact

spawn scp -rp host:~/errfiles/ /home/USERNAME/errfiles/
expect "id_rsa':"
send "PASSWORD\r"
interact

它工作没有任何问题。那我做错了什么?

注意:通常当有人发布关于使用 Expect 使用 scpssh 的问题时,给出的答案是使用 RSA 键。我尝试过,不幸的是,在我的一台计算机上,GNOME key 环存在一些糟糕的错误,这意味着我无法从 RSA key 中删除我的密码,这正是我尝试使用 if 语句编写上述脚本的原因.所以请不要告诉我使用 RSA key 。

最佳答案

您的 Bash 脚本正在 expect 的标准输入上传递 Expect 命令.那就是here-document <<EOD做。然而,expect ...期望其命令在文件中提供,或作为 -c 的参数提供, 根据 man page .下面是三个选项。买者自负;没有经过测试。

  1. Process substitution使用此处文档:

    expect <(cat <<'EOD'
    spawn ... (your script here)
    EOD
    )
    

    EOD结束 here-document,然后整个文件被包裹在 <( ) 中进程替换 block 。结果是 expect将看到一个临时文件名,其中包含您此处文档的内容。

    正如@Aserre 指出的那样,<<'EOD' 中的引号意味着您此处文档中的所有内容都将按字面意思处理。将它们保留下来以在脚本中扩展 Bash 变量等,如果这是您想要的。

  2. 编辑变量+此处-文档:

    IFS= read -r -d '' expect_commands <<'EOD'
    spawn ... (your script here)
    interact
    EOD
    
    expect -c "${expect_commands//
    /;}"
    

    是的,// 之后是一个真正的换行符- 对我来说如何逃避它并不明显。这会将换行符变成分号,即 man page说是必需的。

    感谢this answer对于 read +heredoc 组合。

  3. 外壳变量

    expect_commands='
    spawn ... (your script here)
    interact'
    expect -c "${expect_commands//
    /;}"
    

    注意任何'在 expect 命令中(例如,在 id_rsa 之后)将需要替换为 '\''离开单引号 block ,添加文字撇号,然后重新输入单引号 block 。 // 之后的换行符与前面的选项相同。

关于bash - 在 Bash 脚本中嵌入 Expect 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41165719/

相关文章:

linux - 使用 shell 脚本检查 EOF

mysql - 如何构建在计算中引用选择结果的 MySQL 查询?

bash - 查询 | sed -i 相当于 Windows

expect - 如何计算期望脚本中的命令行参数?

apt-get 错误杀死了我的 bash 函数

python - 存储 GNU 时间命令和脚本的输出

Expect Script - 从某一点开始记录,并在某一点停止

linux - 如何使用expect只记录命令的输出

linux - 是否可以设置 'expect' 的退出代码

linux - 自动化 ssh 登录 : tcl expect interact command behaves weird