Bir yükleme betiğinin süresi boyunca sudo'nun zaman aşımını geçici olarak artırma


22

Bir sürü yazılım yükleyecek bir komut dosyası yazmaya çalışıyorum ve her şeyi olduğu gibi çalıştırmam gerekmek istemiyorum root, bu yüzden bir parola isteyip ardından yükleme işlemine devam etmek, kullanmak sudoveya kullanmak suonlara ihtiyacım olduğunda ayrıcalıklar elde etmek için.

Bir sudo -vbetiğin başında bir şifre sormak için soruyordum ve sonra normalde sudo kullanıyordum. Bu, zaman aşımını devralacak tek bir yüklemeye erişene kadar harika çalışıyor.

Zaman aşımını kalıcı olarak artırmak zorunda kalmamayı tercih ederim. Sudo'nun yalnızca geçerli oturum için zaman aşımını artırabileceğim bir yol var mı?

Yanıtlar:


8

"Sudo -v" yi düzenli aralıklarla yürütmek için arka planda çalışan bir döngü oluşturabilirsiniz, tabii ki püf noktası sonlandırıldığında döngünün temiz bir şekilde sonlanmasını sağlamaktır. Dolayısıyla iki süreç arasında bir tür iletişim olması gerekiyor; tmp dosyaları bunun için uygundur ve script çalıştırıldıktan sonra da kolayca temizlenebilirler. (Bir yükleme betiği genellikle bunu zaten yapar.)

Örneğin (bunu kullanmak için 'echo' ifadelerini kaldırın; bunlar sadece "çalışıyor" gösterir):

#!/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

Sonra göreceksiniz ... (not: PID, tmp dosyasına konur, sadece kolayca öldürebilmeniz için. Yine de gerekli değildir):

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

9

Michael_n'ın cevabını beğendim, ancak geçici bir dosya kullanmamaya dair en mantıksız arzum vardı. Belki bu bir bakış açısı sağlayabilir.

Benim çözümüm:

#!/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!"

Yine, echoyabancı ...

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

Yine, ctrl-c de çalışır ...

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

6
Ve daha özlü bir çözüm: gist.github.com/3118588
Gregory Perkins

Bu nasıl 1000+ artıya sahip değil ??? Özlü sürüm müthiş. (Ama daha iyi bir örnek yardımcı olur sanırım.)
Monica Cellio için MountainX

3

Bu özü temel alarak , özlü ve temiz bir sürüm yaptım:

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

Bence, sürümün daha iyi olacağını düşünüyorum, çünkü sudo -Kkabuk betiğinin başka bir yerine çağrılırsa sürümünüz sudo: a password is requiredher dakika stderr'e bağlanırdı.
Rockallite

@Rockallite Bağlantılı özüm mü demek istiyorsun? Onlar aslında aynı.
Bohr

0

Göre sudoadam sayfası:

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

Bu yüzden sudo -v, oturumu doğrulamak için kurulum betiğinize daha fazla nokta eklerseniz (ve sadece başlangıçta değil) istediğinizi elde edersiniz, çünkü her seferinde zaman aşımını artıracaktır, zaman aşımına ulaşıldı). Tek sorun, betiğinizde zaman aşımından daha fazla zaman alan bir komut varsa (yani ondan hemen sonra doğrulasanız bile zaman aşımı başka bir onaylama için tamamlanmadan önce sona erecek olsa da) olacaktır, ancak bu çok özel bir durumdur.

Olan şu ki, sadece kullanmak sudozaman aşımını arttırmaz ve sudo -vbir komut çalıştırmaz, bu yüzden sudo -voturumu doğrulamak için daha fazla zaman kullanmanız gerekir .


Evet teşekkürler. Sorun şu ki sudo zaman aşımım 5 dakikaya yaklaşıyor ve bundan çok daha önce geçen tek bir make install komutum var.
Arelius,

Hmm. İyi. O zaman zaman aşımını artırmaktan başka yapacak bir şey yok. Geçici olarak ayarlamanın yolu yok.
coredump

0

Baz Ana fikir sağladığı Gregory Perkins ve deneyimlerime, burada benim bir astar var:

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

Veya

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

açıklamalar

  • trap "exit" INT TERM; trap "kill 0" EXIT: Bu işlem, tüm işlem ağacını çıkışta veya SIGINT / SIGTERM'e indirecektir.

  • sudo -v || exit $?: Önceden parola isteyin ve güvenlik kimlik bilgilerini önbelleğe alın, ancak bir komut çalıştırmayın. Şifre doğru değilse, sudo tarafından döndürülen kodla çıkın.

  • sleep 1: Güvenlik kimlik bilgilerinin etkili bir şekilde kaydedilmesi için biraz gecikme. Bir sonraki sudo çok yakında çalışırsa, kimlik bilgileri henüz kaydedilmediğinden bunu bilmeyecek, böylece şifreyi tekrar isteyecektir.

  • while true; do sleep 60; sudo -nv; done 2>/dev/null &: Varolan sudo güvenlik kimlik bilgilerini art arda güncelleyin. Bu sürümün bağlı bulunan oydan birinden farklı olduğuna dikkat edin: önce çalışır sleep 60, sonra çalışır sudo -nv.

    • &Operatör tüm koyar whilebir çocuk süreç olarak çalışan, arka plana döngü.

    • 2>/dev/nullStderr'si yönlendirme whiledöngü içinde herhangi bir komutlar tarafından üretilen hata mesajları atılır, böylece boşluk döngü.

    • -nSeçeneği sudobir şifre gerekli değilse kullanıcıya parola istemeden gelen önler bunu ancak bir hata mesajı gösterir ve çıkar.

    • kill -0 "$$" || exitBağlantılı oyunda olduğu gibi yok , çünkü ilk iki kişi trapişi yapacak. Ana sürecin işe yaramadığını anlaması için 59 saniye uyuması gerekmez!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.