I have the following script:
#!/usr/bin/env python
import sys
import pyttsx
def main():
print 'running speech-text.py...'
engine = pyttsx.init()
str = "Hi..."
if len(sys.argv) > 1:
str = sys.argv[1]
engine.say(str)
engine.runAndWait()
if __name__ == '__main__':
main()
and I have placed it in /usr/bin/speech-test.py
I have also given it executable permissions and ownership to root:
sudo chown root:root /usr/bin/speech-test.py
sudo chmod 4755 /usr/bin/speech-test.py
However, this script will only run correctly if I run as sudo speec-test.py
. If I try to run it as just speech-test.py
it complains about not finding a bunch of ALSA lib files.
Am I missing something to have my script run with root privileges?
So you want the script to run as root
, even without sudo
? For that you would need to set the setuid bit on the script with sudo chmod u+s program
. However, most Unix distributions allow this only for binaries, and not for scripts, for security reasons. In general it's really not a good idea to do that.
If you want to run this script as root, you will have to run as sudo
. Or, you have to create a binary that runs your script, so that you can set the setuid bit on this binary wrapper. This related question explains more.
It's also a good idea to check the effective uid, and if it's not root then stop running. For that, add this near the top (thanks @efirvida for the tip!)
if not os.geteuid() == 0:
sys.exit("\nOnly root can run this script\n")
ORIGINAL ANSWER
Maybe your user and root use a different version of python, with different python path, and different set of libraries.
Try this:
which python
sudo which python
If the two commands don't give the same result then you either need to change the setup of the users to use the same version of python
(the one that has the ALSA libs), or hardcode the python version the first line of the script.
Also try adding a print sys.path
line in the script, and run with your user and with sudo
and compare. Probably you'll get different results. You may need to tweak the PYTHONPATH
variable of your user.
It shouldn't be necessary to make the owner of the script root, and to run it with sudo
. You just need to configure python
and PYTHONPATH
correctly.
I'm not really sure if this is a great method. I tried it and it works fine on arch linux. Let me what you think.
If you write a script to execute the .py as different system group, that group can own a python interpreter and have specified root capabilities.
mkdir roottest && cd roottest
sudo cp /usr/bin/python<ver> ./
sudo groupadd -r rootpython
sudo usermod -a -G rootpython <user>
newgrp rootpython
sudo chown root:rootpython python<ver>
sudo chmod 750 $bin #that way a normal user can't rwx the python interpreter and the rootpython group cant write.
sudo setcap <caps> ./python<ver> #now the group has specify caps allowing it to act like root
sudo getcap ./python<ver>
sudo sh
touch rootfile && echo "original text" > rootfile
open a new prompt as regular user
newgroup rootpython
cd roottest && ./python<ver>
>> open('rootfile', 'w').write("different text")
sudo cat rootfile
This method is way more secure than sudo if used properly because python can only do what you let it and does not have complete control of the system. The downside is having to either make a copy of the interpreter or to not allow the regular user's group to use it. DO NOT run all your python code like this, its a big vulnerability if not needed. The cap_net_admin+ep will allow you to change the kernal var ip_forward and for the example above you need cap_dac_override+ep. You can also create a newuser that belongs to the rootpython group, that way you can't just newgrp rootpython without entering the newuser's password.
Its running privilege is the same as the one who ran it. So if you ran it as yourself, it won't have su privilege. You have to do it sudo
.