在安装脚本期间临时增加 sudo 的超时时间

Are*_*ius 22 scripting linux password sudo

我正在尝试编写一个脚本来安装一堆软件,我不想将所有东西都作为 运行root,所以我希望能够提示输入密码,然后进行安装、使用sudosu在我需要时获得特权。

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

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

小智 9

您可以设置一个在后台运行的循环以定期执行“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
Run Code Online (Sandbox Code Playgroud)

然后你会看到......(注意: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)
Run Code Online (Sandbox Code Playgroud)


Gre*_*ins 9

我喜欢 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!"
Run Code Online (Sandbox Code Playgroud)

再次,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
Run Code Online (Sandbox Code Playgroud)

同样,ctrl-c 也可以工作...

$ ./sudoping.sh 
Starting background sudo ping...
ok  
Sudo ping!
Sudo pinging in PID = 47599
Sudo ping!
^CStopping sudo ping in PID = 47599
Run Code Online (Sandbox Code Playgroud)

  • 还有一个更简洁的解决方案:https://gist.github.com/3118588 (6认同)

Boh*_*ohr 5

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

# 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 &
Run Code Online (Sandbox Code Playgroud)