在安装脚本的持续时间内暂时增加 sudo 的超时时间

在安装脚本的持续时间内暂时增加 sudo 的超时时间

我正在尝试编写一个脚本来安装一堆软件,但我不想以 的身份运行所有软件root,因此我希望能够提示输入密码,然后进行安装,使用sudosu在需要时获取权限。

我在脚本开始时提示sudo -v输入密码,然后稍后正常使用 sudo。这很好用,直到我找到一个可以接管超时的安装。

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

答案1

您可以设置一个在后台运行的循环,定期执行“sudo -v”,当然,诀窍是让循环在脚本终止时干净地终止。因此,两个进程之间必须有某种类型的通信;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)

答案2

我喜欢 michael_n 的回答,但又非常不理智地不想使用临时文件。也许这可以提供一些观点。

我的解决方案是:

#!/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's 是多余的......

$ ./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

答案3

基于此要旨,我做了一个简洁干净的版本:

# 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 &

答案4

根据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在安装脚本中添加更多点来验证会话(而不仅仅是在开始时),您将获得想要的结果,因为每次它都会增加超时时间(只有在达到超时时间时才会再次询问密码)。唯一的问题是,如果脚本中的命令所花的时间比超时时间更长(因此,即使您在它之后立即进行验证,超时时间也会在完成另一次验证之前到期),但这是一个非常特殊的情况。

发生的情况是,仅仅使用sudo不会增加超时,也sudo -v不会执行命令,因此您必须使用sudo -v更多时间来验证会话。

相关内容