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:
- 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.
- 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
.
Prefix every command (that requires it) with sudo
inside the script
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.