Solusi 1:
Anda dapat mengatur loop yang berjalan di latar belakang untuk mengeksekusi "sudo -v" secara berkala, triknya tentu saja membuat loop berhenti dengan bersih saat skrip Anda berakhir. Jadi harus ada semacam komunikasi antara kedua proses tersebut; File tmp baik-baik saja untuk ini, dan mereka dapat dengan mudah dibersihkan setelah skrip berjalan juga. (Skrip pemasangan biasanya melakukan ini.)
Misalnya (hapus pernyataan 'gema' untuk menggunakan ini; ini hanya menunjukkannya "berfungsi"):
#!/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
Kemudian Anda akan melihat... (catatan:pid dimasukkan ke dalam file tmp, supaya Anda dapat dengan mudah mematikannya. Namun, ini tidak perlu):
$ ./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)
Solusi 2:
Saya menyukai jawaban michael_n, tetapi memiliki keinginan paling tidak rasional untuk tidak menggunakan file temp. Mungkin ini bisa memberikan beberapa perspektif.
Solusi saya adalah:
#!/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!"
Sekali lagi, echo
itu asing...
$ ./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
Sekali lagi, ctrl-c juga berfungsi...
$ ./sudoping.sh
Starting background sudo ping...
ok
Sudo ping!
Sudo pinging in PID = 47599
Sudo ping!
^CStopping sudo ping in PID = 47599
Solusi 3:
Berdasarkan intisari ini, saya telah membuat versi yang ringkas dan bersih:
# 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 &