临时增加安装脚本持续时间的sudo超时

我试图编写一个脚本,将安装一堆软件,我不想以root身份运行一切,所以我想能够提示input密码,然后去安装,使用sudosu在我需要时获得特权。

我正在做一个sudo -v在脚本的开头提示input密码,然后通常在后面使用sudo。 这很好,直到我到达一个接pipe超时的单一安装。

我宁愿不必永久增加超时。 有没有办法可以增加sudo的当前会话超时?

你可以设置一个在后台运行的循环来定期执行“sudo -v”,当然这个技巧是让脚本终止的时候干净地终止循环。 所以这两个过程之间必须有某种forms的沟通。 tmp文件对此很好,而且脚本运行后也可以很容易地清理它们。 (无论如何,安装脚本通常会这样做。)

例如(删除'echo'语句来使用这个;这些只是显示它“工作”):

 #!/bin/bash log=running_setup.txt sudo_stat=sudo_status.txt echo "========= running script $$ ========" echo $$ >> $sudo_stat trap 'rm -f $sudo_stat >/dev/null 2>&1' 0 trap "exit 2" 1 2 3 15 sudo_me() { while [ -f $sudo_stat ]; do echo "checking $$ ...$(date)" sudo -v sleep 5 done & } echo "=setting up sudo heartbeat=" sudo -v sudo_me echo "=running setup=" | tee $log while [ -f $log ] do echo "running setup $$ ...$(date) ===" | tee -a $log sleep 2 done # finish sudo loop rm $sudo_stat 

然后你会看到…(注意:pid被放到了tmp文件中,所以你可以很容易地杀死它,但这并不是必须的):

 $ ./do_it.sh ========= running script 6776 ======== =setting up sudo heartbeat= [sudo] password for user: =running setup= checking 6776 ...Wed May 4 16:31:47 PDT 2011 running setup 6776 ...Wed May 4 16:31:48 PDT 2011 === running setup 6776 ...Wed May 4 16:31:50 PDT 2011 === running setup 6776 ...Wed May 4 16:31:52 PDT 2011 === checking 6776 ...Wed May 4 16:31:53 PDT 2011 running setup 6776 ...Wed May 4 16:31:54 PDT 2011 === <ctrl-c> (cleans up files, then exits) 

我喜欢michael_n的回答,但有最不合理的愿望不使用临时文件。 也许这可以提供一些观点。

我的解决scheme是:

 #!/bin/bash function sudo_ping() { if [[ ! -z $SUDO_PID ]]; then if [[ $1 -eq stop ]]; then echo "Stopping sudo ping in PID = $SUDO_PID" kill $SUDO_PID return else echo "Already sudo pinging in PID = $SUDO_PID" return fi fi echo "Starting background sudo ping..." sudo -v if [[ $? -eq 1 ]]; then echo "Oops, wrong password." return fi sudo echo "ok" while true; do echo 'Sudo ping!' sudo -v sleep 1 done & SUDO_PID=$! sudo echo "Sudo pinging in PID = $SUDO_PID" # Make sure we don't orphan our pinger trap "sudo_ping stop" 0 trap "exit 2" 1 2 3 15 } sudo_ping sleep 5 echo "Goodbye!" 

再次, echo是无关的…

 $ ./sudoping.sh Starting background sudo ping... Password: ok Sudo ping! Sudo pinging in PID = 47531 Sudo ping! Sudo ping! Sudo ping! Sudo ping! Goodbye! Stopping sudo ping in PID = 47531 

再次,ctrl-c的作品也…

 $ ./sudoping.sh Starting background sudo ping... ok Sudo ping! Sudo pinging in PID = 47599 Sudo ping! ^CStopping sudo ping in PID = 47599 

基于这个要点 ,我做了一个简洁而干净的版本:

 # Prevent sudo timeout sudo -v # ask for sudo password up-front while true; do # Update user's timestamp without running a command sudo -nv; sleep 1m # Exit when the parent process is not running any more. In fact this loop # would be killed anyway after being an orphan(when the parent process # exits). But this ensures that and probably exit sooner. kill -0 $$ 2>/dev/null || exit done & 

根据sudo手册页面:

  -v If given the -v (validate) option, sudo will update the user's time stamp, prompting for the user's password if necessary. This extends the sudo timeout for another 15 minutes (or whatever the timeout is set to in sudoers) but does not run a command. 

所以我想,如果你在安装脚本的更多点添加一些sudo -v来validation会话(而不仅仅是在开始),你会得到你想要的,因为每次会增加超时(它只是要求如果达到超时,再次input密码)。 唯一的问题是,如果你的脚本有一个比超时更多的时间的命令(所以即使你在它之后validation超时将在它完成另一个validation之前过期),但这是一个非常特殊的情况。

会发生什么,只是使用sudo不会增加超时,而sudo -v不会执行一个命令,所以你必须多次使用sudo -v来validation会话。

基于Gregory Perkins提供的要求和我的经验,这里是我的一行:

 trap "exit" INT TERM; trap "kill 0" EXIT; sudo -v || exit $?; sleep 1; while true; do sleep 60; sudo -nv; done 2>/dev/null & 

要么

 trap "exit" INT TERM trap "kill 0" EXIT sudo -v || exit $? sleep 1 while true; do sleep 60 sudo -nv done 2>/dev/null & 

说明

  • trap "exit" INT TERM; trap "kill 0" EXIT trap "exit" INT TERM; trap "kill 0" EXIT :这将取消退出或SIGINT / SIGTERM整个进程树。

  • sudo -v || exit $? :提前询问密码并caching安全凭证,但不要运行命令。 如果密码不正确,请使用sudo返回的代码退出。

  • sleep 1 :稍微延迟一点,以便有效保存安全证书。 如果下一个sudo运行得太快,它将不知道,因为凭证还没有保存,因此将再次要求密码。

  • while true; do sleep 60; sudo -nv; done 2>/dev/null & while true; do sleep 60; sudo -nv; done 2>/dev/null & :重复更新现有的sudo安全凭证。 注意这个版本与链接的要点不同:它首先运行sleep 60 ,然后运行sudo -nv

    • &运算符将整个while循环放入后台,将其作为subprocess运行。

    • 2>/dev/nullwhile循环的stderrredirect到void,所以循环内的任何命令生成的错误消息将被丢弃。

    • sudo-n选项可防止提示用户input密码,但会显示错误消息并在需要密码时退出。

    • 有没有kill -0 "$$" || exit kill -0 "$$" || exit ,因为前两个trap会做的工作。 在计算出父进程没有运行之前,它不需要睡59秒。