8

Let's say, I have the following bash script:

#!/bin/bash
sudo command1
command2
sudo command3

I don't want to run command2 as root, so I won't run the script itself with sudo. Therefore, as soon as I execute the script, sudo command1 asks for my password. Unfortunately, command2 takes about 2 hours to complete. So the sudo credentials timestamp timed out and when the script reaches sudo command3, I'm prompted for the password again.

I don't want to permanently disable the sudo credentials timestamp timeout altogether as described in https://superuser.com/a/149740 for example. I just want to disable the timeout temporarily, effectively keep the credentials for this one bash session until it ends.

2
  • 1
    Kick off a background job to run sudo -v every 5 minutes (e.g. watch -n 600 sudo -v &), for the duration of the command2 execution.
    – steve
    Commented Apr 19, 2019 at 16:35
  • 1
    @steve that's a good idea; you'd have to ensure that sudoers was configured with !requiretty, as it wouldn't have a tty in the background
    – Jeff Schaller
    Commented Apr 19, 2019 at 16:38

4 Answers 4

5

I think your best bet is a (backgrounded) busy-wait loop that refreshes the sudo timestamp, which you then kill when you no longer need sudo privileges. Here's a sample script; it runs sleep 6 instead of your two-hour command2 and runs visible /bin/echo commands instead of command1 and command2:

#!/bin/sh
sudo /bin/echo command 1
while :; do sudo -v; sleep 1; done &
infiloop=$!
sleep 6
sudo /bin/echo command 3
kill "$infiloop"

For your actual script, I would recommend a looser loop:

#!/bin/sh
sudo command1
while :; do sudo -v; sleep 59; done &
infiloop=$!
command2
sudo command3
kill "$infiloop"

Adjust the sleep 59 to taste, depending on the existing timestamp_timeout setting in sudoers; I chose 59 just to demonstrate a choice you could make if the timestamp timeout was 60 seconds.

1
  • You can also use trap to ensure that the kill command is executed upon exiting the script. Commented Sep 19, 2023 at 19:01
4

I must be missing something here, because the solution seems very obvious to me.

I don't want to run command2 as root, so I won't run the script itself with sudo.

But you can run the whole script with sudo without running command 2 as root if you change the script:

#!/bin/bash
command1
sudo -u ${SUDO_USER:-$USER} command2
command3
1
  • Why would I test it without sudo? You didn't say you needed to run it both with and without sudo.
    – EmmaV
    Commented Oct 6, 2019 at 15:57
1

By refreshing credentials in the background:

#!/bin/bash


configurePermissions () {
    sudo -v
    refreshPermissions "$$" &
}


refreshPermissions () {
    local pid="${1}"

    while kill -0 "${pid}" 2> /dev/null; do
        sudo -v
        sleep 10
    done
}


configurePermissions
0

Well, it would be possible to combine How can I make sudo forget the password automatically after one command? and What's the purpose of using `sudo -S` explicitly?

  1. Read password from user, save it in environment variable
  2. Run sudo with -k flag to ignore credentials so it will always prompt for the password
  3. Pass the password via stdin into sudo with flag -S
  4. Remove password environment variable

It might be useful for certain situations, but I'm not sure if it's a good idea to store the user's password in an environment variable.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .