I am writing a python script that needs to make a log entry whenever it's invoked. The log created by the script must not be changeable by the user (except root) who invoked the script. I tried the syslog module and while this does exactly what I want in terms of file permissions, I need to be able to put the resulting log file in an arbitrary location. How would I go about doing this?
I see you are on linux,
Depending on which filesystem you are using, you may be able to use the chattr command. You can make files that are append only by setting the a attribute
Run your script with setuid root.
Related
So I've been trying to modify .bash_aliases programatically for a while now, and I've been running into issues with every method I've tried.
Running my script using sudo python3 myscript.py causes the script to modify the .bash_aliases file of the root user. I can't find a way to determine what user ran the script to modify their file.
Trying to use a shell command such as sudo echo "my string" >> ~/.bash_aliases gets an error: sh: 1: cannot create /home/migue/.bash_aliases: Permission denied, presumably because sudo can't display its password prompt when I call it programatically.
I can't find a way to temporarily get root permissions after determining the full path (ie expanding ~) of the file.
Basically, I'd love to know any reasonable method to modify and append to .bash_aliases through a Python script. I haven't found any questions on this where the solutions worked for me.
I'd prefer for this method to not require any non-standard modules, as installing them will just make the process less seamless for people who use the script.
I can't find a way to determine what user ran the script to modify their file.
You can reference the file ~/.bash_aliases in your script and run it without sudo, unless your current user is root.
EDIT:
You simply need to add write privileges to .bash_aliases for every user it belongs to.
I'm attempting to run a python script that creates a custom menu inside Maya when a .bat file is opened to start Maya. The python script is not inside the Maya project and I wanted to add the path in the batch file. I have this in the .bat file:
start D:\TOOLS\Maya2019\bin\maya.exe -command evalDeferred(python('execfile(\"D:\CustomMenu_startup.py\")'))
Several attempts already but it's returning a syntax error.
solved by using:
start D:\TOOLS\Maya2019\bin\maya.exe -command evalDeferred(python(\"execfile('D:\\CustomMenu_startup.py')\"))
I'd suggest that, as a rule, it'd be better to push the deferred evaluation into the python itself. That way you don't have to think about it in all 3 languages (BAT, MEL, and Python).
There may also be parts of the work you can execute before the main Maya event loop kicks in, which will save some startup time -- evaldeferred is the safe choice before touching the Maya UI or the scene but you might have other jobs (like downloading files or checking the user's disk) that can be done safely while Maya itself is still loading. That's another reason to do the deferred part in Python instead of in the outermost MEL call.
If you're interested in generating launchers like this you can simply distribute a mel file instead of the BAT; MEL is executable by Maya as a file argument so your commandline gets simpler and if you have the correct file associations set up it's double-clickable.
You might also want to check out these blog posts about how to create python launchers for Maya:
https://theodox.github.io/2018/pythonception#pythonception
https://theodox.github.io/2018/keystone#keystone
I currently have a Python scrip that runs through all Excel files in the current directory and generates a PDF report.
It works fine now but I don't want the users to be anywhere near frozen Python scripts. I created an MSI with cxFreeze which puts the EXE and scripts in the Program Files directory.
What I would like to be able to do is create a shortcut to this executable and pass the directory the shortcut was run from to the Python program so that can be set as the working directory. This would allow the user to move the shortcut to any folder of Excel files and generate a report there.
Does Windows send the location of a opened shortcut to the executable and is there a way to access it from Python?
When you launch a shortcut, Windows changes the working directory to the directory specified in the shortcut, in the Start in field. At this point, Windows has no memory of where the shortcut was stored.
You could change the Start in field to point to the directory that the shortcut is in. But you'd have to do that for every single shortcut, and never make a mistake.
The better approach is to use a script, rather than a shortcut. Place your actual Python script (which we'll call doit.py for sake of example) somewhere in your PYTHONPATH. Then create a single-line Python script that imports it:
import doit
Save it (but don't name it doit.py) and copy it to each directory from which you want to be able to invoke the main script. In doit.py you can use os.getcwd() to find out what directory you're being invoked from.
You could also do it with a batch file. This is a little more flexible in that you can specify the exact name of the script and which Python interpreter should be used, and don't need to store the script in a directory in PYTHONPATH. Also, you don't need to worry about the file's name clashing with the name of a Python module. Simply put this line in a file:
C:\path\to\your\python.exe C:\path\to\your\script.py
Save it as (e.g.) doit.bat and copy it into the directories from which you want to invoke it. As before, your Python script can call os.getcwd() to get the directory. Or you can write it so your Python script accepts it as the first argument, and write your batch file like:
C:\path\to\your\python.exe C:\path\to\your\script.py %cd%
Another thing you can do with the batch file approach is add a pause command to the end so that the user is asked to press a key after the script runs, giving them the opportunity to read any output generated by the script. You could even make this conditional so that it only happens if an error occurs (which requires returning a proper exit code from the script). I'll leave that as an exercise. :-)
Is there a problem with modifying the script to take the directory to process as a command line argument?
You could then configure the different shortcuts to pass in the appropriate directory.
Type the following into a batch file (i.e. script.bat):
python \absolute\path\to\your\script.py %~dp0
pause
Then add these imports at the top of your python file script.py (if not already included):
import os
import sys
And add this to the bottom of the python file (or combine it with a similar statement):
if __name__ == "__main__":
# set current working directory:
if len(sys.argv) > 1:
os.chdir(sys.argv[1])
main()
replace main() with whatever function you want to call or code you want to run.
The following is how I came to my answer:
I tried using kindall's answer and had the following issues:
The first suggestion of storing the script somewhere in PYTHONPATH could not be applied to my situation because my script will be used on a server and needs to be independent of the client computer's python environment (besides having the required pip installations).
I tried calling my python script from a Windows Batch File which could be moved to a different location. Instead of the batch file's location being used as the current working directory, it was C:\Windows.
I tried passing %cd% as an argument to my python script, then setting that to be my CWD. This still resulted in a CWD of C:\Windows.
After reviewing the comments, I tried Eryk Sun's suggestion of instead passing %~dp0 as an argument to the python script. This resulted in the CWD being correctly set to the batch file's location.
I hope this helps others facing similar difficulties.
I have a script that, when run, creates a directory inside /home/test/ and then writes some files in it. When I run this script, it works fine. However, when I call it from a perl script with
$ret = `/home/..../testscript.py`
it doesn't have permissions so it can't create the folder, or can't write inside it after it is created. It looks like when Python does open("/home/test/abcde/file1.txt", "w"), that file has permissions -rw-r--r--
What can I do to get around this? Is there a way to set /home/test to recursively make all subdirectories have global write-access? Or a better solution maybe?
Put:
os.umask(0000)
in the Python script before it creates the directory. If you can't change the Python script, put:
umask(0000)
in the Perl script before it calls the Python script.
When a new file or directory is created, the permissions are determined by taking the permissions specified in the call to creat() or mkdir(), and then masking off the bits that are specified in the umask.
Typically, applications specify 0666 or 0777 permissions when they call the function (depending on whether they're creating something that should be executable or not). A common value for umask is 022, which turns off group and world write permissions. If you don't want them turned off, use the above umask value to keep the permissions specified in the call.
I need a better way to prevent normal users from executing my python script. I'm doing something like that:
if __name__ == '__main__':
if os.getenv('USER') == 'root':
addUser = addUser()
else:
print 'Only root can run that!'
It's working, but it's pretty ugly!
My script is about user management in a Debian system.
Python code can be viewed and edited to circumvent any protection you put in, your best bet is to restrict executable access by user in debian so only root can execute/view/edit.
See chmod
It's more normal to restrict access to the resources an executable needs to work than to enforce permissions at the level of the executable. For example, the mount(8) command can normally be run by any user, but the device files needed to actually mount real volumes are restricted to certain users or groups, and the mount command checks to see if the operation would be possible before even attempting to make the syscalls to perform the device operations.
This works as well with regular files. For instance, many linux package managers require a database of installed programs. Before installing anything, the package manager will check the permissions on the database file to see if the calling user could write to it, and also checks the destination directories to see if the user could modify those. even if the package manager does not perform these checks, they can't make those changes when they try, the kernel simply prevents the program from performing an action the owning user is not permitted to make.