There are a number of ways to do this.
- Use absolute paths instead of relative paths (this defeats the purpose of having it in your path, though).
- Make a separate script that invokes sudo and converts things into absolute paths.
- Add your script to the system with update-alternatives.
- Put your script in a different path that is meant for this sort of thing (it'll be a system path--not one in your home directory).
- Add a new path (whether or not it's in your home directory) to be the sort of path needed to do this sort of thing. You'll need to have an understanding of the underlying security reasons for things if you do this.
- Invoke sudo from your script itself (instead of outside of it). Same goes for aliases and functions.
While #4 and #5 may work, I don't think most people want to bother with that, as it might butcher your system and open you up to security vulnerabilities if you do it wrong; plus there's a learning curve (and I don't know all the ins and outs of that, yet). So, I'm going to give you a simple non-invasive solution using #2, and then I'll tell you how to do #3.
Okay, here's a Python 3.x script that I wrote; I just called it sud
and put it in ~/bin
(in Ubuntu, that will automatically put it in your regular path; you don't need to put it in an ultra special path usable with sudo). The script essentially invokes sudo and has it do what sudo does. However, if you want to invoke your own script that is in your regular path, preface it with a comma (to make it turn it into an absolute path to your script), and preface regular relative paths that aren't in your path with a + (to turn them into absolute paths to your files); be sure to do chmod u+x ~/bin/sud
(to make it executable for the current user; for security reasons, there's probably no sense making it executable for anyone else as chmod +x
and chmod a+x
do). Yes, you can unambiguously use flags and options with sudo and the calling program this way.
#!/usr/bin/env python3
"""
This is like sudo, except it finds the absolute paths for scripts if they begin with a comma, and it finds the absolute paths for filepaths if they begin with a plus. It also uses an absolute path for sudo. The aim is to allow a flexible way for all scripts in the path to be run with sudo, while keeping the user conscious of which ones don't naturally run with sudo.
It should also be able to be used like sudo for the uses that sudo already works for. Obviously, it will cause problems if your files or commands begin with + or , naturally. So, don't use it on those.
Example usage:
sud ,myscript
sud +mypath
sud ,myscript +mypath
sud app
sud app path
"""
import subprocess, sys, os, shutil
sys.argv[0]=shutil.which("sudo")
i=1
while i<len(sys.argv):
if sys.argv[i].startswith(","):
sys.argv[i]=sys.argv[i][1:]
sys.argv[i]=shutil.which(sys.argv[i])
elif sys.argv[i].startswith("+"):
sys.argv[i]=sys.argv[i][1:]
sys.argv[i]=os.path.abspath(sys.argv[i])
i+=1
subprocess.run(sys.argv)
Okay, now the update-alternatives option. This requires root privileges initially. It also puts your script in your path (so you can put it wherever; it doesn't have to be in your path first). It also makes the script available systemwide, if its location is available systemwide. Don't move your script after you do this, or it'll break the command.
First of all, choose a name for your script that isn't in use on your system (otherwise this will be more complicated and I'm not going to bother explaining how to handle the more complicated stuff right now).
Add the following lines to your ~/.bashrc
file:
enter() {
sudo update-alternatives --install /usr/bin/"$1" "$1" $(realpath "$1") 0
}
Save and exit. Exit the terminal and open another one. Now, whenever you type enter myScriptName
(be sure you're in the same directory as it when you do it, and use a relative path that is only your script name) it will add that script to your path in a way that will make it usable with and without sudo. Be sure to set your permissions and file location appropriately if you're in a multi-user environment (i.e. probably not in your home directory, and make sure the permissions aren't something like 0600, but rather something like 0555).
If you want to remove such a script from your path after having added it with update-alternatives, do this (it doesn't matter which directory you're in):
sudo update-alternatives --remove-all myScriptName
You can use update-alternatives to add them manually, too, of course, instead of using my enter
function above. So, if you want to add /opt/Programs/myScript
to your path, you could do this:
sudo update-alternatives --install /usr/bin/myScript myScript /opt/Programs/myScript 0
Then you can type these things from anywhere to invoke it:
- myScript [myArgs]
- sudo myScript [myArgs]
sudo
you should use the full path to the script, i.e. if in your home~
directory it would besudo bin/myScript
orsudo /home/user/bin/myScript
.