我在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密码并让脚本在此之后继续运行,该怎么办?
我不想将密码保存在脚本中,然后将其传递给期望值,但是我希望能够输入。
答案 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