1

I have a question from this thread How to run a bash script by double clicking by entering the path in sudoers?. Since it was explained to me that it is unsafe to grant sudo privileges to the script.sh file, I decided to find a way to double-click the script.sh file without granting sudo privileges to the file itself. And to make it safe.

I'm using Debian 12 with the KDE Plasma desktop environment. To run the command sudo sh /path/to/script.sh, you need to go to a terminal, type sudo sh /path/to/script.sh, and then enter the password. I want to have a file I can double click in the UI which will then run the sudo sh /path/to/script.sh, so all I need to do after double clicking is just enter the password.

There are commands inside the script that only work with sudo, such as ip tuntap add dev,, or route add. How can I do this?

Thanks.

0

2 Answers 2

4

EDIT

Since you edited your comment to provide more information, I can now give you a complete answer. I verified with my friend who runs KDE plasma, and he says that the default behavior is that double-clicking a script on the desktop will launch it, provided that the executable bit is set. It doesn't launch it in a terminal, so the script has to create its own terminal. With that in mind, here are the instructions:

  1. Add a shebang to your script

Add the line #!/bin/sh to the very start of your script. This tells you system which shell to use to execute your file.

  1. Make the file executable

Right click on the file and under permissions, tick the checkbox that says executable. Alternatively, run chmod +x /path/to/script.sh.

  1. Prefix every command (that requires it) with sudo inside the script

  2. Make sure the script opens in a terminal

You can do this by adding the following snippet at the start of your script (but after the shebang):

test "$IN_TERM" || {
    export IN_TERM=1
    konsole --hold -e "$0"
    exit 0
} && true

This uses Konsole, KDE's default terminal. The --hold flag makes sure that the terminal stays open after the script is finished, so that you can verify that it runs correctly.

That's it, everything should work!

Example

Just to get an overview of what everything should look like, here is a similar script I have on my system. Instead of changing network settings, it changes my laptop's charging behavior, but the overall idea is similar.

#!/bin/sh

set -x  # Print all commands before running them
set -e  # Exit on first error

test "$IN_TERM" || {
    export IN_TERM=1
    alacritty --hold -e "$0"  # I use alacritty as my terminal.
    exit 0
} && true

sudo -v  # Ask for password, but don't run any command

# Subsequent invocations of `sudo` won't ask for password
sudo tpacpi-bat -s ST 1 0
sudo tpacpi-bat -s SP 1 0

echo 'Done!'

Security

In the comments, you were mentioning that you were worried about putting sudo inside the script itself. I'm not a security researcher, but let me assure you that this is completely fine and secure. sudo will still prompt the user for the password. Any other user on the system, or a malicious program running with your user's permissions, won't be able to take advantage of your script in any way. Putting sudo in scripts may be frowned upon, but for reasons unrelated to security (e.g. putting sudo in a script may be problematic if you intend to distribute this script to other people, since not everybody has sudo installed).

Old answer

As the comments pointed out, we can't really help you, since you didn't tell us what distro / desktop environment you're using.

However, I can give you some pointers.

Move the sudo inside the script

I think in this situation it would be best for you to move the sudo invocation into the script itself. You can do it by putting something like this at the start of the script:

test "$(id -u)" -eq 0 || {
    sudo sh "$0"
    exit 0
}

Another option is to create a second script that launches the first with sudo. And a third option is to simply prefix any of the root-only commands in your script with sudo. It will only ask for the password once.

Set the executable bit

In the terminal, run chmod +x /path/to/script.sh. This makes the file executable. You can test that it works by launching the script with /path/to/script.sh as opposed to sh /path/to/script.sh. In some desktop environments, this may also make the script runnable by double-clicking it through the GUI.

Set the correct shebang

Make sure your script starts with #!/bin/sh (or #!/bin/bash (or #!/usr/bin/env bash) if you script uses bash-only features)

Dig around in your distro's settings app

Double clicking to launch scripts may be disabled due to security reasons. Try looking for this option in your file managers or desktop environments settings. Here

Create a .desktop file.

If the above fails, you can create a file called myscript.desktop with the following contents (and edit the Type, Comment, and Exec fields):

[Desktop Entry]
Version=1.0
Type=Application
Name=your_human_friendly_name
Comment=your_human_friendly_comment
Exec=/path/to/script.sh
Terminal=false
StartupNotify=false
Categories=Application;

You can now double-click this file to run your script. Note that you will need to move the sudo into your script. If you need your script to launch inside a terminal, change the Terminal field. Note that your script needs to have the executable bit set for this approach to work.

Another bonus of .desktop files is that if you put it into /usr/share/applications or ~/.local/share/applications, it will also be accessible through your application launcher.

Also, there is a tool called gendesk to automatically make .dekstop files for you, but writing them by hand also works.

Use gksudo

If you do figure out how to achieve the behavior that you want, it may still be impossible to run your script if your desktop environment launches it without a terminal, since there would be no way for you to type your password for sudo. Consider installing the package gksudo (may have a different name depending on distro) and using it instead of sudo. It works the same way, but creates a GUI password entry box instead of using the terminal

Make the script launch its own terminal

In case you need the script to launch in a terminal for reasons other than interacting with sudo (e.g. displaying output to the user), you can put this at the beginning of your script (but after the shebang) to make sure it always launches in the terminal:


test "$IN_TERM" || {
    export IN_TERM=1
    alacritty --hold -e "$0"
    exit 0
} && true

Please note that the above snippet uses alacritty, which is my preferred terminal. Change that to whatever terminal you use. Also note the --hold and -e flags, which are also alacritty-specific. -e is actually -c on most other terminals.

Use rofi

This doesn't answer your question, but I think you might find it useful. If you find yourself having a lot of different scripts that you need to be able to launch quickly, consider rofi. It will allow you to have a searchable menu of all your scripts, ready to launch. To use rofi this way, you first need to create a script (let's call it rofi_launch.sh) that looks something like this:

#!/bin/bash

if [ -z "$1" ]; then
    ls /path/to/where/you/store/your/scripts
else
    FILE="/path/to/where/you/store/your/scripts/$1"
    killall rofi
    "$FILE" & disown
fi

Then, launch rofi with rofi -show RUN:/path/to/rofi_launch.sh (you can bind this to a keyboard shortcut in your desktop environment's settings) and you should have a menu from where you can launch any of your scripts.

13
  • I have a question from this thread unix.stackexchange.com/questions/762272/…. Since it was explained to me that it is unsafe to grant sudo privileges to the script.sh file, I decided to find a way to double-click the script.sh file without granting sudo privileges to the file itself. And to make it safe. There are commands inside the script that only work with sudo, such as ip tuntap add dev, route add.
    – moninah
    Commented Nov 27, 2023 at 6:39
  • @moninah that makes absolutely no difference to security. What is unsafe is to allow users to run the script without requiring sudo, which is what your original question was asking.
    – terdon
    Commented Nov 27, 2023 at 8:49
  • @terdon So I want to run a bash file without adding it to sudoers (because it's not secure). But also so as not to constantly open the terminal and type commands first and then the password. I would like to put commands into a bash file and double-click on it and type the password.
    – moninah
    Commented Nov 27, 2023 at 11:59
  • Yes, isn't this what this answer provides? Maybe you missed it because the answer gives a lot of useful information, but if you create a .desktop file (see "Create a .desktop file" in the answer) and use sudo sh /path/to/script.sh, and set Terminal=true, then you will be able to do exactly what you say.
    – terdon
    Commented Nov 27, 2023 at 11:59
  • @renzev This code displays a console and a password field, but commands that work with sudo do not run: test "$IN_TERM" || { export IN_TERM=1 konsole --hold -e "$0" exit 0 } && true sudo -v <command ...>. By creating a shortcut and specifying Terminal=true, the script starts and works. As I understand it, with the shortcut you can simply use the command sudo -s <<EOF <command ...> EOF. But I would like to be able to run the script without creating a shortcut.
    – moninah
    Commented Nov 27, 2023 at 15:20
0

I'm just a bit late here, and renzev already has a great answer for you. However, for the sake of completeness, I feel compelled to mention pkexec. Usage is as simple as pkexec /path/to/script.sh (assuming the script has its executable bit set). Also, this approach pairs very nicely with a .desktop file.

pkexec (or really, polkit, the mechanism to which it belongs) is another standard way of escalating privileges, and tends to pair more effectively with graphical desktops. If you've used a tool like Gparted that requires root access, it usually achieves that by popping up a graphical password prompt — that's polkit in action.

The specific pop-up is actually provided by your desktop environment, and as a result, window manager users may need to explicitly install one. Since you mentioned using Plasma, you'll have one built in already.

You must log in to answer this question.

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