how to run chmod in python? - python

I was working with a sensor called Rplidar. To connect the Rplidar with my operating system(Ubuntu) sometimes i have to use this command in the terminal:
sudo chmod 666 /dev/ttyUSB0
After running this instruction, ubuntu can detect the Rplidar. Later on, i will run a python script to work with the Rplidar. Now I want to include this command inside my python script so that i do not need to run it in the terminal before working with the Rplidar. Is there any way that i could do it in python script?

The simple answer is that chmod is provided in the os module in Python:
https://docs.python.org/3/library/os.html#os.chmod
so all you need to do is run:
import os
filename = 'example.dat'
os.chmod(filename,
stat.S_IRUSR |
stat.S_IWUSR |
stat.S_IRGRP |
stat.S_IWGRP |
stat.S_IROTH)
so there's no need to shell out to perform this operation normally. Also have a look at the os.path and shutil modules for much more support in this area.
Things get a little complicated if you need to perform this operation with elevated privileges, but that's actually not the solution here.
Also, it is not a good idea to give 666 permissions to system devices. This can open up security problems when any user on the system has read/write access to system devices. As a matter of principle, use the least permissions required for correct operation.
As #KlausD. comments, you shouldn't be forcing permission changes on these device nodes anyway. The correct approach is to perform a one-time operation of adding the relevant user to the dialout group on your system. Then by being in the correct group, the user running your application will have access to the device. This is already answered here:
https://askubuntu.com/questions/112568/how-do-i-allow-a-non-default-user-to-use-serial-device-ttyusb0
Just run this once:
sudo adduser kazi dialout
then log out and back in for it to take effect. Your Rplidar app will run fine.

You can use the subprocess library to run shell command in Python
import subprocess
subprocess.Popen(["sudo", "chmod", "666", "/dev/ttyUSB0"], stdout=subprocess.PIPE, shell=True)

Related

Run external applications using Python and call their methods inside

Wish You all beautiful sunny day! :D,
I have a question for You guys. I have following python "script":
import os
os.system('ubuntu.exe')
Which opens Ubuntu running on my WSL. And now, when the Ubuntu terminal appears:
I would like to execute following commands: sudo /etc/init.d/dbus start and sudo /etc/init.d/xrdp start using my python script (just do them automatically). However, when I run one of the commands above, terminal requests my password:
So the script should be also able to enter the password.
Is there any way, how to do it?
Kind regards,
D.
While the question/answers linked in the comments is a good read (sudoers in particular), there's a better method for WSL. Instead of using ubuntu.exe, use the newer wsl.exe replacement. The wsl command offers more control over the startup, including being able to change the user:
import os
os.system('wsl ~ -u root -e sh -c "nohup service xrdp start"')
os.system('wsl -u root service dbus start')
The nohup is needed because of what seems to be a timing issue. When starting up via the WSL command, the shell (owning process) will terminate before xrdp gets a chance to fork. nohup just makes sure that the full xrdp init script gets a chance to run before that happens. This really isn't a WSL issue, per se. It can also be replicated if you were do something similar with exec sh -c "sudo service xrdp start".
A couple of other notes. First, this does not require a password, since WSL doesn't have the concept of "login." The /init process (WSL's PID1 and initialization) is responsible for setting the owning user for each session. This is not considered a security risk since even the root WSL user runs with no greater than the permissions of the Windows user.
Also note that, in my experience, it's not necessary to start dbus for xrdp access, even though I've seen instructions that say it is. Ultimately it will depend on what you want to run within the xrdp session, of course.

Run python as root using cap_sys_admin capability linux

I have the following capability of python2.7 (using getcap):
/usr/bin/python2.7 = cap_sys_admin+ep
I know that CAP_SYS_ADMIN is "CAP_SYS_ADMIN is a highly privileged access level and should generally be avoided as it is equivalent to root access level." (https://docs.bridgecrew.io/docs/bc_k8s_36)
It's mean that I can run as root using /usr/bin/python2.7?
So how actually I can get example root bash using /usr/bin/python2.7?
Setting cap_sys_admin on /usr/bin/python means that python will be able to make any 'root' system call. This means that any one who runs python has the power to do things that normally only root can do. If someone (maliciously or accidentally) tries to do something dangwerous, they won't be stopped. Something as simple as the following could be catastrophic:
import shutil
shutil.rmtree('/')
In most cases if you need a script to run with elevated privileges it is better to use a user account that has these permissions, using su or sudo, rather than making a command always run without limits. That way you can focus on 'who' is allowed to do thingsm rather than 'what'.

How to open a "root" file without typing your password every time?

I read this very interesting post, which is very close to what I need but not completely, they use it for shell scripting while I need the same solution mainly for a built-in Python function.
Long story short:
open("/dev/input/event3", "rb")
This doesn't work out of the box because in order to open event3 I need to type my password every single time I execute my Python script, due to elevated privileges. What can I do so I don't have to type my password every time nor write my password in plane text in my script? I like the solution offered in the post I linked above, but this doesn't work because that would mean the -sort of speak- handle I get on this open file will be in another scope/python script.
Any solutions?
Thanks
EDIT
I tried modifying the privileges of my entire Python script, so that I don't need to type a password, but that didn't work neither. What I tried:
1) modify access rights
sudo chown root:root /home/username/myscript.py
sudo chmod 700 /home/username/myscript.py
2) modify visudo
myusername ALL=(ALL) NOPASSWD: /home/username/myscript.py
3) trying to execute my python script now fails, altough it is clearly there
myusername$ ./myscript
bash: ./myscript: No such file or directory
It occurs to me that you may be approaching this problem backward. Currently, you're asking how you can elevate the permissions of a python script without entering a password every time when you should be asking, "why do I need to enter a password at all?"
As long as the file isn't a security concern both the script and the file in question should be owned by non-root users in the input group. The user who owns the python script can then execute it without root privileges to access the file which doesn't require them.
Read more about setuid. It is tricky (so I won't even try to explain it here), and is the basis of authentication related programs like sudo, su, login etc. See also setreuid(2), setuid(2), execve(2), credentials(7), chmod(1).
A good Unix programming book (such as ALP, or something newer) should explain setuid in terms of system calls (listed in syscalls(2)).
setuid executables cannot be scripts (with shebang); they should be binary ELF executables (see elf(5)). However, you could write some setuid wrapper program in C (or most other compiled languages, e.g. Rust, Ocaml, C++, Go, ...) which runs your Python script. Be careful, since a mistake could open a huge security hole. But with such a setuid executable, you won't have to type any password.
You could also have some specific user or group owning the /dev/input/event3 (so configure appropriately your system for that, thru udev or systemd...) and have a setuid or setgid program.
BTW, you could configure sudo (see sudoers(5) and this) to avoid typing any password. Of course, that weakens the security of your entire system (but the choice is yours).
You can pass the sudo password in the same line with the command, using this syntax:
echo password | sudo -S your_command
This way you won't be prompted for sudo password before the command can execute - sounds like that's what you are looking for.

run imposm commands from a python script

I'm just getting started using imposm to help get openstreetmap data into a postgis database. All the docs point to making all commands via Terminal. This is fine for one off imports but I plan to have many many imports of varying bounding boxes and would like to script the loading of the data in the database.
Currently I use:
imposm --overwrite-cache --read --write -d postgis_test --user postgres -p "" /Users/Me/MapnikTest/osmXML.osm
Which works fine from the command line but as osmXML.osm is being created many times I would like somehow to import this at the point of creation.
Putting the same thing in a python script as:
os.system("imposm --overwrite-cache --read --write -d postgis_test --user postgres -p "" /Users/Ali\ Mac\ Pro/Desktop/MapnikTest/osmXML.osm")
just returns:
/bin/sh: imposm: command not found
Solving this would be the final step to automate the acquisition of data to render small maps on demand but I'm falling at the final hurdle!
** Edit full path to imposm solved the first problem but imputing the password for the postgres user happens when prompted. Is there a way to send the password in the same single line command? (maybe this needs to be a new post?, happy if someone points me in the right direction)**
This is probably because os.system() is calling /bin/sh which uses a different shell environment from the one you use when working on the command line.
To work around this, in your script, get the full path to the imposm script and then use that in your command. Use can use some code like this to find the executable.
Or you can fix your shell definitions so that /bin/sh has the proper PATH defined, but that depends greatly on your setup...
Solved with the help of further research and the comments from #Eli Rose (many thanks): find out what path to imposm (or whichever command you are trying to make) with
which <command>
Then include the path in the python shell command. Using a module from subprocess you can even see the full terminal output.
import subprocess
from subprocess import *
print Popen("/usr/local/bin/imposm --overwrite-cache --read --write --connection postgis://<database user>:<password>#<host>/<database> /path/to/data.osm", stdout=PIPE, shell=True).stdout.read()
The
--connection postgis://<database user>:<password>#<host>/<database>
means you can make the command in a single line and not have to worry about entering the database user password in a following command.

Python - running a script as a service with a name other than 'python'

I have a set of python scripts which I run as a daemon services. These all work great, but when all the scripts are running and I use top -u <USER>, I see all my scripts running as python.
I would really like to know which script is running under which process id. So is there any way to execute a python script as a different process name?
I'm stuck here, and I'm not ever sure what terms to Google. :-)
Note: I'm using Ubuntu Linux. Not sure if the OS matters or not.
Try using setproctitle. It should work fine on Linux.
Don't have a linux system here to test this on appropriately, but if the above doesn't work, you should be able to use the same trick they use for things like gzip etc.
The script has to tell what to run it at the top like this:
#!/usr/local/bin/python
Use a softlink like this:
ln -s /usr/local/bin/python ~/bin/myutil
Then just change your script to
#!~/bin/myutil
and it should show up that way instead. You may need to use a hard link instead of a soft link.
Launching a python script using the python script itself (and file associations and/or shell magic) is not very portable, but you can use similar methods on nearly any OS.
The easiest way to get this is using she bang. The first line of your python script should be:
#!/usr/bin/python
or
#!/usr/bin/python3
depending upon whether you use python or python3
and then assign executable permissions to the script as follows:
chmod +x <scriptname>
and then run the script as
./scriptname
this will show up as scriptname in top.

Categories