Make all new directories have 777 permissions - python

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.

Related

Modify .bash_aliases with Python

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.

Call a Python script (in a directory in the PATH) from command line with Windows

With Linux, if you create a file mycommand with +x permission in a folder which is in the PATH, containing a Python shebang #!..., then calling mycommand from command line works, no matter the current directory.
How to have the equivalent on Windows? i.e. I have a folder D:\myscripts\ which is in the PATH, containing a few personal scripts like mycommand.py.
How to make that calling mycommand or maybe just python mycommand from commandline will work, no matter the current working directory?
TL;DR: I'd like to avoid to have to do
python D:\myscripts\command.py
each time I want to call every-day-use personal scripts from D:\myscripts\
Note: .py files are associated with my text editor (i.e. when double-clicking on a .py file, it is opened with the text editor) and I want to keep this.
Solution 1
I finally did like this:
put D:\myscripts\ in the PATH (with setx, see How to update system PATH variable permanently from cmd?)
create a batch file: D:\myscripts\mycommand.bat containing:
#python d:\myscripts\mycommand.py
That's it!
Solution 2
Here is a solution from various comments from #ErykSun:
Open the system environment variables editor and ensure that "D:\myscripts" is in PATH (do not use quotes) and ".PY" is in PATHEXT (do not use quotes).
Create a test file D:\myscripts\test_command.py with the line import sys; print(sys.executable); print(sys.argv).
In a new command prompt that was opened from Explorer (to get the updated environment variables), run the test script from another directory as test_command spam eggs. If it runs with the expected Python installation and the command-line arguments "spam" and "eggs" are correctly passed, then you're done.
When double-clicking and running at the command prompt, the shell executes the default action for the filetype. If the filetype doesn't explicitly define a default action, the shell uses the "open" action, and if that's not defined it uses the filetype's first defined action, whatever that is. Python configures an "open" action for its "Python.File" filetype and additional context-menu (right-click) actions for editing with IDLE.
There are other directions you can go with this. You can use shell links. Add ".LNK" to PATHEXT and remove ".PY". Then for each script that you want to run, create a shell link (.LNK shortcut file) in D:\myscripts that runs the script explicitly as "path\to\python.exe" "\path\to\script". Leave the working directory field empty, so that it inherits the working directory of the parent process. For example, create D:\myscripts\test_command.lnk to run D:\myscripts\test_command.py.
In this case, you would run the script as test_command, which will find and execute "test_command.lnk". To get the default Sublime edit action, you would explicitly run test_command.py with the ".PY" extension.
Solution 3
Create an .exe file in c:\python37\scripts\ with this method: How to create a .exe similar to pip.exe, jupyter.exe, etc. from C:\Python37\Scripts?
but it's more complicated since it requires a package, etc.

Is it possible to access the launching shortcut directory from a Python executalbe?

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.

subprocess.check_output ignoring euid

I have the following bash script:
echo "$(id -u)"
mkdir test
My own user id is 1000. Now, when I run python3.5 without root rights and invoke the script via subprocess.check_output the script works as expected and creates a folder which is owned by me.
However, when I start python with sudo but then use os.setegid(1000); os.setuid(1000), the script outputs 0 and the folder "test" is owned by root. While I get that echo "$(id -u)"may be desired behavior, I do not get why this folder is owned by root. Shouldn't the os.seteuid() function prevent that?
My exact call is:
>>> os.setegid(1000)
>>> os.seteuid(1000)
>>> subprocess.check_output(["/.script.sh"])
Which results in the folder "test" being owned by root. Is this desired behavior and if so, is there any way I can start the script as a normal user while still being able to back to root rights in the python script (i.e., not setting the "real" uid?)
setegid only sets the effective group id of the current process. Same with seteuid.
check_output spawns a new process, which is still apparently still run as root.
You might have more luck if you attempt to create your folder using python instead of shelling out to do it, but I imagine this is a simpified example so that may not be appropriate. Is it possible to run the python script as the expected user? If not you might need to do something like this;
subprocess.check_output(["sudo", "-uexpected_user", "./script.sh"])

Creating Read-only logs with python

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.

Categories

Resources