Skip to content

Instantly share code, notes, and snippets.

@cowboy
Created July 15, 2012 20:55
Show Gist options
  • Star 90 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save cowboy/3118588 to your computer and use it in GitHub Desktop.
Save cowboy/3118588 to your computer and use it in GitHub Desktop.
Bash: Sudo keep-alive (good for long-running scripts that need sudo internally but shouldn't be run with sudo)
#!/bin/bash
# Might as well ask for password up-front, right?
sudo -v
# Keep-alive: update existing sudo time stamp if set, otherwise do nothing.
while true; do sudo -n true; sleep 60; kill -0 "$$" || exit; done 2>/dev/null &
# Example: do stuff over the next 30+ mins that requires sudo here or there.
function wait() {
echo -n "["; for i in {1..60}; do sleep $1; echo -n =; done; echo "]"
}
wait 0 # show reference bar
echo "$(sudo whoami) | $(date)"
wait 1
echo "$(sudo whoami) | $(date)"
wait 2
echo "$(sudo whoami) | $(date)"
wait 5
echo "$(sudo whoami) | $(date)"
wait 10
echo "$(sudo whoami) | $(date)"
wait 15
echo "$(sudo whoami) | $(date)"
wait 1
sudo -K
echo "$(whoami) | $(date)"
wait 2
echo "$(whoami) | $(date)"
wait 5
echo "done."
Copy link

ghost commented Oct 29, 2016

I was thinking about something like this but it doesn't handle the case where sudo expires immediately

@reitermarkus
Copy link

reitermarkus commented Oct 30, 2016

@spudowiar, I recently changed my dotfiles to use the sledge-hammer approach to sudoing by adding myself to /etc/sudoers for the duration of the script, because anything else just wouldn't work reliably.

https://github.com/reitermarkus/dotfiles/blob/f104a8a7a592204a66646810ae8fbd956023c988/.sh#L43-L60

Maybe that will work for your case.

@thomaspaulmann
Copy link

Awesome... That's exactly what I'm looking for. Unfortunately it does not work with a long running task like a massive brew install. After that, the sudo session is expired and you have to re-enter a password for the next sudo command. @cowboy Do you have any hints/experiences on that?!

@rockallite
Copy link

I think the following statement:

while true; do sudo -n true; sleep 60; kill -0 "$$" || exit; done 2>/dev/null &

Should be changed to:

while true; do sleep 60; sudo -n true; kill -0 "$$" || exit; done 2>/dev/null &

Because an immediate call to sudo right after the first one is not only redundant, but would also cause sudo to ask password again for the second real sudo call (at lease in my testing case).

@cowboy
Copy link
Author

cowboy commented Mar 3, 2017

Awesome... That's exactly what I'm looking for. Unfortunately it does not work with a long running task like a massive brew install. After that, the sudo session is expired and you have to re-enter a password for the next sudo command. @cowboy Do you have any hints/experiences on that?!

Homebrew explicitly invalidates the sudo timestamp, so AFAIK there's no way for this to work with brew.

@JemarJones
Copy link

@cowboy are you saying that this attempt at a solution didn't work? https://gist.github.com/cowboy/6733297

@tzeikob
Copy link

tzeikob commented Aug 25, 2021

Has anyone tried this solution with the following sequence of commands:

sudo apt-get -y update
sudo apt-get -y upgrade
sudo apt-get -y autoremove

local packages=(tree curl unzip htop gconf-service gconf-service-backend gconf2
            gconf2-common libappindicator1 libgconf-2-4 libindicator7
            libpython2-stdlib python python2.7 python2.7-minimal libatomic1
            gimp vlc)

sudo apt-get -y install ${packages[@]}

sudo apt-get -y update

# At this point it asks me again the password
sudo apt-get -y install gufw

For me it didn't work.

Does sudo count the times is called along with the timeout? Because I see I'm using a few redundant apt-get update.

FYI: I'm running ubuntu 20.04

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment