Bash 在expect脚本中输入sudo密码
我在bash脚本中有一个expect代码,类似这样Bash 在expect脚本中输入sudo密码,bash,tcl,expect,Bash,Tcl,Expect,我在bash脚本中有一个expect代码,类似这样 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)\
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
env-input1=${input1}input2=${input2}expect自man-sudo
:除非在sudoers(5)中被重写,否则sudoers策略会将凭据缓存15分钟
这样,在调用expect之前先调用sudo-v
。它会检查凭据,如果没有缓存,它会询问根密码。这样,您就可以在expect
之前输入它们,以后sudo
命令无需再次询问。关于您的评论,我认为您在cron中有它。在这种情况下,您需要以sudo的身份运行脚本。你可以在sudo crontab中调用它。您可以通过运行sudo crontab-e
来访问它。处理此类事件的标准方法是观察sudo密码提示,提供它,然后继续。但是对于长时间运行的脚本,您将希望在expect脚本中缓存密码,这样您就不必在几个小时内多次返回到用户那里。事实上,对于可用性,您可能需要提前询问密码,而不是等到底层系统需要密码
幸运的是,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
env input1=${input1}input2=${input2}expectDonal Fellows的答案是正确的,但为了完整性,这里是您尝试的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上的脚本运行expect,因此,除非您使用-u tty\u spawn\u id
使其与/dev/tty
和用户一起工作,否则interact会出现问题。您需要在这个tty上显式地设置echo on/off,因为sudo只会在生成的命令和expect之间的pty上进行设置。让用户以交互方式控制expectinteract
功能就是为了这个。我找不到使用interact
的好例子。我尝试了类似于“{interact-o”\r“return;exp\u continue}
”的密码,但一个问题是我键入的内容是可见的,另一个问题是,在我按下ENTER键后,什么也没有发生,脚本无法继续工作。如果你想让专家期待的话,我可能需要一个tcl
标签。(expect
是TCL语言的一个扩展,不是bash的一部分;因为您的问题与如何从bash启动expect无关,而与启动后它的行为有关,这不是bash的问题。)另一个_脚本.sh
将执行几个小时,所以缓存的凭据在此期间超时。@adamm您可以为NOPASSWD
访问向/etc/sudoers
添加相关命令吗?我不能这样做。在cron中运行时,您绝对不能与用户交谈,而必须从其他地方获取凭据。在所有选项中,从文件中读取是最好的选择之一。或者您可以简单地将脚本放在root的crontab中,而不需要任何凭据……谢谢您的评论。我尝试了您的建议,但我发现执行“发送用户”\n“
时出现以下错误:sudo password:send:spawn id exp0未打开。
您提到我可以监视提示,提供它,然后继续。我该怎么做?我想这就是原始问题的答案,可能是将expect脚本包装到bash脚本中的方式(我刚刚从您那里复制)。我仍然不知道为什么编写expect脚本的人喜欢这样做。这是因为我不想为expect脚本再增加一个文件。我有一个很大的bash脚本,我希望其中有一些提示(输入1和输入2)Expect
似乎是解决这个问题的方法,所以我只是将Expect“嵌入”到bash脚本中。@adamm我想我已经通过将send\u user
和Expect\u user
分别更改为send\u tty
和Expect\u tty
解决了这个问题。我认为stty不需要更改。它现在可以工作了。这不是我一直在寻找的问题,但它是非常有用的。