在期望脚本中输入sudo密码

时间:2019-04-14 21:02:22

标签: bash tcl expect

我在bash脚本中有一个期望代码,像这样

env input1=${INPUT1} input2=${INPUT2} expect << "EOS"
    set timeout -1
    spawn ./another_script.sh
    expect {
        "Input 1" { send -- "$env(input1)\r";exp_continue }
        "Input 2" { send -- "$env(input2)\r";exp_continue }
        eof
    }
EOS

在执行another_script.sh的过程中,系统提示我输入sudo密码,但由于无法满足要求,所以我无法输入密码。 为了使我能够输入sudo密码并让脚本在此之后继续运行,该怎么办? 我不想将密码保存在脚本中,然后将其传递给期望值,但是我希望能够输入。

4 个答案:

答案 0 :(得分:2)

处理此类事件的标准方法是观察sudo密码的提示,提供该密码,然后继续。但是,使用长时间运行的脚本,您将需要在期望脚本中缓存密码 ,这样您就不必在数小时内多次返回给用户。确实,出于可用性的考虑,您可能需要先询问密码,而不是等到基础系统需要密码时。

幸运的是,expect包括对stty的支持,因此添加起来很容易。

env input1=${INPUT1} input2=${INPUT2} expect << "EOS"
    # Prompt for password, cribbed/converted from example on expect(1) manpage
    stty -echo
    send_tty "sudo password: "
    expect_tty -re "(.*)\n"
    send_tty "\n"
    set password $expect_out(1,string)
    stty echo

    # Rest of the script, with clause for sending the password at the right time
    set timeout -1
    spawn ./another_script.sh
    expect {
        "Input 1" { send -- "$env(input1)\r"; exp_continue }
        "Input 2" { send -- "$env(input2)\r"; exp_continue }
        "assword: " { send -- "$password\r"; exp_continue }
        eof
    }
EOS

答案 1 :(得分:2)

Donal研究员的答案是正确的方法,但是为了完整起见,这里是您正在尝试的interact解决方案。使用的命令是

expect {
    "Input 1" { send -- "$env(input1)\r"; exp_continue }
    "Input 2" { send -- "$env(input2)\r"; exp_continue }
    "password for" { stty -echo
                    interact -u tty_spawn_id -o "\r" return
                    stty echo
                    exp_continue }
    eof
}

您遇到的问题是您正在对stdin上的脚本运行“期望”,因此除非您使用-u tty_spawn_id使其与/dev/tty和用户一起使用,否则交互会遇到麻烦。您需要在此tty上显式设置打开/关闭回显,因为sudo只会在生成的命令和期望之间的pty上完成它。

答案 2 :(得分:0)

man sudo开始:sudoers策略将凭据缓存15分钟,除非在sudoers(5)中被覆盖。

这样,在致电Expect之前先致电sudo -v。它会检查凭据,如果未缓存凭据,则会要求输入root密码。这样,您可以在expect和更高版本的sudo命令之前输入它们,而无需再次询问。

答案 3 :(得分:0)

对于您的评论,我认为您已将其列入cron。在这种情况下,您需要将脚本作为sudo运行。您可以在sudo crontab中调用它。您可以通过运行sudo crontab -e

进行访问