3

I wrote these two scripts and they are in my $PATH:

gsudo:

#! /bin/bash
sudo -n true &> /dev/null
if [ $? -eq 0 ]
then
  sudo "$@"
else
  upass=$(zenity --password --title "Enter your password" 2> /dev/null)
  [[ ! -z "$upass" ]] && echo $upass | sudo -S -p "" "$@"
fi

This script essentially does the same thing what gksu does. It looks if sudo needs password or not and according to the result of that it will ask password or not.

run-something:

gsudo command1
gsudo command2

If I run the second script from a terminal window, I get the expected behavior. It simply asks for my password only one time. But if I call it from a graphical environment, like a task runner(I tried i3wm dmenu and rofi launcher) it asks for my password two times. So why is this happening, how can I fix it? I believe sudo -n true should return the same thing both times, because it's getting called in same script so sudo session should persist. I'm not trying to save sudo session between different script calls, it's enough that it persists only in one call.

isamert
  • 143

1 Answers1

1

I did some tests. It's not (yet) completely clear to me how sudo caches one's ability to elevate. Probably it has something to do with pseudoterminal being allocated or not.

If I were you I would implement what you can read in this question: How do I run a sudo command inside a script? Especially from one of the answers:

It is rarely a good idea to have sudo inside scripts. Instead, remove the sudo from the script and run the script itself with sudo

except in your case it's your gsudo we're talking about. Additionally I would use $SUDO_USER, if necessary (from this other answer).

Example run-something:

#!/path/to/my/gsudo /bin/bash

# The shebang ensures the below code is for sure run with gsudo bash;
# gsudo runs sudo, which sets $SUDO_USER (see `man sudo').

command1   # This is run with gsudo because the entire script is.

# Get back to the invoking (possibly regular) user for just one command
sudo -u "$SUDO_USER" command_whatever

# Again as root
command2
command3

# Get back to the invoking user for many commands
sudo -u "$SUDO_USER" bash << EOF

foo
bar
baz

EOF

My gsudo would be very simple:

#!/bin/bash
SUDO_ASKPASS='/path/to/my/gsudo_helper' sudo "$@"

And gsudo_helper:

#!/bin/bash
zenity --password --title "Enter your password" 2> /dev/null

Notes:

  • I deliberately don't use sudo -A in gsudo code. This way gsudo uses a terminal if available, zenity otherwise.
  • The syntax sudo "$@" allows gsudo to pass command line options (like the mentioned -A) to sudo. This is rather a good idea but if you don't want it then consider sudo -- "$@".