Using python to check write permission in a ntfs file system - python

I need to write into several files that usually needs higher level permission than a regular user. Before doing anything, I would like the check if the current user can write in all of them. If so, proceed to writing. Otherwise warns the user and asks to check first the user level permission.
In nix systems, like Linux and Mac OS, I can rely on os.access, but it seems that simply does not work on Windows. It tells that the file always have write permission, but proceeding to the writing I stumble in an unexpected exception of PermissionError - Permission denied.
I saw the StackOverflow link pointing to the win32security (Checking folder/file ntfs permissions using python). But the topic is 10 years old, and checking for library today, it doesn't seems that library is currently supported or mantained.
Snippet to check permission:
import os
if os.name == 'posix':
file_to_write = '/etc/hosts'
else:
file_to_write = 'C:\\Windows\\System32\\drivers\\etc\\hosts'
if os.access(file_to_write, os.W_OK):
print("I can write in!")
else:
print("Can't write. No permission.")
Then, the code to write in the file:
import os
if os.name == 'posix':
file_to_write = '/etc/hosts'
else:
file_to_write = 'C:\\Windows\\System32\\drivers\\etc\\hosts'
file_resource = open(file_to_write, 'a')
file_resource.write("\ntest")
file_resource.close()
Testing my snippets, using python3, in any operational system, or even testing any file in the system (not necessarily the hosts file in my example), python shall tells previously if the file can be written by the current user. If so, then the second snippet must not return an exception of PermissionError - Permission denied, and the target file shall have a word "test" in the file's last line. Otherwise, I won't even try the second snippet.
In Windows environment, python dumbly tells that any existing file have write permission.

Maybe use a with statement that automatically closes. 'a+' will create the file if it does not already exist and append the file. For reading and writing you can use 'r+':
import os
if os.name == 'posix':
file_to_write = '/etc/hosts'
else:
file_to_write = 'C:\\Windows\\System32\\drivers\\etc\\hosts'
with open('file_to_write', 'a+') as file_resource:
file_resource.write("\ntest") # .close() is automatically called
If this does not work the permission error will be because you are trying to write to a path that needs a user privilege. If that is the case consider using an alternative of the chmod on a Linux machine. In windows you can change the settings by right clicking the file. Navigate to the properties settings, then the security settings to allow 'write'

Related

I Got a Permission Error After Installing This Game

I have this function from a game class:
def store_data(self):
if self.score > self.best_score:
with open("best_score.txt", "w") as file:
msg = f"BEST SCORE: {self.score}"
file.write(msg)
file.close()
I want to store the best_score in this txt file (if there is a better way of storing data in python you're welcome to correct me, thank you)
I finished the game and I used pyinstaller + NSIS to get a single file, and of course, I installed it on my device, before installing there is no issue, but after installing and running the game from my local desk C:\\ I got this error:
PermissionError: [Errno 13] Permission denied: 'best_score.txt'
So please, could you help me.
Thank you.
The user executing the code doesn't have the required permission. Maybe you're running the code in a directory which requires admin privilege (and since you do not provide a path, Python tries to save the file in that dir) or maybe another user created the file.
I recommend storing the result in (a sub-path of) the user's home directory, e.g.
import os
USER_HOME: str = os.path.expanduser("~")
with open(f"{USER_HOME}/best_score.txt", "w") as file:
# do stuff

os.access returns True, but file is not writable

I have this code:
import os
print(os.access("tst.txt", os.R_OK))
open("tst.txt", "rb")
# File Permissions:
# Owner: Trusted Installer
# Administrators and my user: deny all permissions
os.access returns True but opening the file raises a PermissionError exception.
And if I try this on another file (like cmd.exe, notepad.exe, System32 dir itself, or ANY other file) it always returns True.
If a file is non-existent it return False.
SO: True on any existing file. Even if there is no write access.
I couldn't find anything about this on the Internet.
Does anybody know why this issue occurs?
EDIT:
Of course my script is not running as Administrator.
No matter if I test read or write access.
It looks like os.access does not check user permissions on Windows, it only checks for the readonly flag being set or not.
Note that os.access doesn't check file security on Windows. W_OK just checks the read-only flag. Thus using try...except is really the only possibility if you're on Windows and aren't using the Windows security API .
from http://net-informations.com/python/file/exists.htm
In this case, you may have to wrap a try...except around your code

"/Library" directory permission denied on Mac - Python3

I'm trying to create a program that copies a directory in the library directory on mac (path : "/Library"). I use shutil which works very well in other directories but not in the Library directory...
I want to be able to compile my program, so I can't run it as root.
Here is my code :
import shutil
def copy(src_path, dir_path):
try:
shutil.copytree(src_path, dir_path)
print("Success!")
except:
print("Impossible to copy the folder...")
print("Failed!")
copy("/Users/marinnagy/Desktop/Test", "Library/Test")
I think it's because the library directory is protected and requires authentication to make changes.
Do I have to make an authentication request to the user ? Or do I need to use another method than shutil ?
Thanks for your help !
After a good deal of research and many attempts, I finally managed to copy a folder into my Library directory.
On macOS, the process of writing to a protected directory like the Library directory is blocked for python program. Once compiled (I use pyinstaller), it seems to be impossible for a python application to access this kind of folder, even if you give the app Full Disk Access in the System Preferences.
So I used some AppleScript to manage this specific copy/paste task :
on run {scr_path, dir_path} # Run with arguments
# Translate standard paths to their quoted form
set formated_scr_path to quoted form of scr_path
set formated_dir_path to quoted form of dir_path
# Run a simple shell script to copy the repertory in the other
do shell script "cp -R " & formated_scr_path & space & formated_dir_path ¬
with administrator privileges # Ask for administrator privileges
end run
Then, in my python program, I call the AppleScript program when I want to copy/past to a protected repertory like the Library repertory :
import subprocess
def copy(scr_path, dir_path):
# Use the osascript process to call the AppleScript
# Give the paths in arguments
process = subprocess.call(['osascript', "path/to/applescript",
scr_path, dir_path])
return process
copy("path/to/folder 1", "path/to/folder 2")
This method worked for me on protected repertories. The AppleScript run in the background and an authentication window pop in, asking the user to identify himself as an admin :
result screenshot

Thing to check if you have permissions to directory

I'm writting an python program and now I'm working at exceptions.
while True:
try:
os.makedirs("{}\\test".format(dest))
except PermissionError:
print("Make sure that you have access to specified path")
print("Try again specify your path: ", end='')
dest = input()
continue
break
It is working but later I need to delete that folder.
What is the better way to do it?
Don't.
It is almost never worth verifying that you have permissions to perform an operation that your program requires. For one thing, permissions are not the only possible reason for failure. A delete may also fail because of a file lock by another program, for instance. Unless you have a very good reason to do otherwise, it is both more efficient and more reliable to just write your code to try the operation and then abort on failure:
import shutil
try:
shutil.rmtree(path_to_remove) # Recursively deletes directory and files inside it
except Exception as ex:
print('Failed to delete directory, manual clean up may be required: {}'.format(path_to_remove))
sys.exit(1)
Other concerns about your code
Use os.path.join to concatenate file paths: os.makedirs(os.path.join(dest, test)). This will use the appropriate directory separator for the operating system.
Why are you looping on failure? In real world programs, simply aborting the entire operation is simpler and usually makes for a better user experience.
Are you sure you aren't looking for the tempfile library? It allows you to spit out a unique directory to the operating system's standard temporary location:
import tempfile
with tempfile.TemporaryDirectory() as tmpdir:
some_function_that_creates_several_files(tmpdir)
for f in os.walk(tmpdir):
# do something with each file
# tmpdir automatically deleted when context manager exits
# Or if you really only need the file
with tempfile.TemporaryFile() as tmpfile:
tmpfile.write('my data')
some_function_that_needs_a_file(tmpfile)
# tmpfile automatically deleted when context manager exits
I think what you want is os.access.
os.access(path, mode, *, dir_fd=None, effective_ids=False, follow_symlinks=True)
Use the real uid/gid to test for access to path. Note that most operations will use the effective uid/gid, therefore this routine can be used in a suid/sgid environment to test if the invoking user has the specified access to path. mode should be F_OK to test the existence of path, or it can be the inclusive OR of one or more of R_OK, W_OK, and X_OK to test permissions. Return True if access is allowed, False if not.
For example:
os.access("/path", os.R_OK)
And the mode contains:
os.F_OK # existence
os.R_OK # readability
os.W_OK # writability
os.X_OK # executability
Refer: https://docs.python.org/3.7/library/os.html#os.access

PermissionError: [Errno 13] Permission denied

I'm getting this error :
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python34\lib\tkinter\__init__.py", line 1538, in __call__
return self.func(*args)
File "C:/Users/Marc/Documents/Programmation/Python/Llamachat/Llamachat/Llamachat.py", line 32, in download
with open(place_to_save, 'wb') as file:
PermissionError: [Errno 13] Permission denied: '/goodbye.txt'
When running this :
def download():
# get selected line index
index = films_list.curselection()[0]
# get the line's text
selected_text = films_list.get(index)
directory = filedialog.askdirectory(parent=root,
title="Choose where to save your movie")
place_to_save = directory + '/' + selected_text
print(directory, selected_text, place_to_save)
with open(place_to_save, 'wb') as file:
connect.retrbinary('RETR ' + selected_text, file.write)
tk.messagebox.showwarning('File downloaded',
'Your movie has been successfully downloaded!'
'\nAnd saved where you asked us to save it!!')
Can someone tell me what I am doing wrong?
Specs :
Python 3.4.4 x86
Windows 10 x64
This happens if you are trying to open a file, but your path is a folder.
This can happen easily by mistake.
To defend against that, use:
import os
path = r"my/path/to/file.txt"
assert os.path.isfile(path)
with open(path, "r") as f:
pass
The assertion will fail if the path is actually of a folder.
There are basically three main methods of achieving administrator execution privileges on Windows.
Running as admin from cmd.exe
Creating a shortcut to execute the file with elevated privileges
Changing the permissions on the python executable (Not recommended)
A) Running cmd.exe as and admin
Since in Windows there is no sudo command you have to run the terminal (cmd.exe) as an administrator to achieve to level of permissions equivalent to sudo. You can do this two ways:
Manually
Find cmd.exe in C:\Windows\system32
Right-click on it
Select Run as Administrator
It will then open the command prompt in the directory C:\Windows\system32
Travel to your project directory
Run your program
Via key shortcuts
Press the windows key (between alt and ctrl usually) + X.
A small pop-up list containing various administrator tasks will appear.
Select Command Prompt (Admin)
Travel to your project directory
Run your program
By doing that you are running as Admin so this problem should not persist
B) Creating shortcut with elevated privileges
Create a shortcut for python.exe
Righ-click the shortcut and select Properties
Change the shortcut target into something like "C:\path_to\python.exe" C:\path_to\your_script.py"
Click "advanced" in the property panel of the shortcut, and click the option "run as administrator"
Answer contributed by delphifirst in this question
C) Changing the permissions on the python executable (Not recommended)
This is a possibility but I highly discourage you from doing so.
It just involves finding the python executable and setting it to run as administrator every time. Can and probably will cause problems with things like file creation (they will be admin only) or possibly modules that require NOT being an admin to run.
Make sure the file you are trying to write is closed first.
Change the permissions of the directory you want to save to so that all users have read and write permissions.
You can run CMD as Administrator and change the permission of the directory using cacls.exe. For example:
cacls.exe c: /t /e /g everyone:F # means everyone can totally control the C: disc
In my case the problem was that I hid the file (The file had hidden atribute): How to deal with the problem in python:
Edit: highlight the unsafe methods, thank you d33tah
# Use the method nr 1, nr 2 is vulnerable
# 1
# and just to let you know there is also this way
# so you don't need to import os
import subprocess
subprocess.check_call(["attrib", "-H", _path])
# Below one is unsafe meaning that if you don't control the filePath variable
# there is a possibility to make it so that a malicious code would be executed
import os
# This is how to hide the file
os.system(f"attrib +h {filePath}")
file_ = open(filePath, "wb")
>>> PermissionError <<<
# and this is how to show it again making the file writable again:
os.system(f"attrib -h {filePath}")
file_ = open(filePath, "wb")
# This works
I had a similar problem. I thought it might be with the system. But, using shutil.copytree() from the shutil module solved the problem for me!
The problem could be in the path of the file you want to open. Try and print the path and see if it is fine
I had a similar problem
def scrap(soup,filenm):
htm=(soup.prettify().replace("https://","")).replace("http://","")
if ".php" in filenm or ".aspx" in filenm or ".jsp" in filenm:
filenm=filenm.split("?")[0]
filenm=("{}.html").format(filenm)
print("Converted a file into html that was not compatible")
if ".aspx" in htm:
htm=htm.replace(".aspx",".aspx.html")
print("[process]...conversion fron aspx")
if ".jsp" in htm:
htm=htm.replace(".jsp",".jsp.html")
print("[process]..conversion from jsp")
if ".php" in htm:
htm=htm.replace(".php",".php.html")
print("[process]..conversion from php")
output=open("data/"+filenm,"w",encoding="utf-8")
output.write(htm)
output.close()
print("{} bits of data written".format(len(htm)))
but after adding this code:
nofilenametxt=filenm.split('/')
nofilenametxt=nofilenametxt[len(nofilenametxt)-1]
if (len(nofilenametxt)==0):
filenm=("{}index.html").format(filenm)
It Worked perfectly
in my case. i just make the .idlerc directory hidden.
so, all i had do is to that directory and make recent-files.lst unhidden after that, the problem was solved
I got this error as I was running a program to write to a file I had opened. After I closed the file and reran the program, the program ran without errors and worked as expected.
I faced a similar problem. I am using Anaconda on windows and I resolved it as follows:
1) search for "Anaconda prompt" from the start menu
2) Right click and select "Run as administrator"
3) The follow the installation steps...
This takes care of the permission issues
Here is how I encountered the error:
import os
path = input("Input file path: ")
name, ext = os.path.basename(path).rsplit('.', 1)
dire = os.path.dirname(path)
with open(f"{dire}\\{name} temp.{ext}", 'wb') as file:
pass
It works great if the user inputs a file path with more than one element, like
C:\\Users\\Name\\Desktop\\Folder
But I thought that it would work with an input like
file.txt
as long as file.txt is in the same directory of the python file. But nope, it gave me that error, and I realized that the correct input should've been
.\\file.txt
As #gulzar said, I had the problem to write a file 'abc.txt' in my python script which was located in Z:\project\test.py:
with open('abc.txt', 'w') as file:
file.write("TEST123")
Every time I ran a script in fact it wanted to create a file in my C drive instead Z!
So I only specified full path with filename in:
with open('Z:\\project\\abc.txt', 'w') as file: ...
and it worked fine. I didn't have to add any permission nor change anything in windows.
That's a tricky one, because the error message lures you away from where the problem is.
When you see "__init__.py" of an imported module at the root of an permission error, you have a naming conflict. I bed a bottle of Rum, that there is "from tkinter import *" at the top of the file. Inside of TKinter, there is the name of a variable, a class or a function which is already in use anywhere else in the script.
Other symptoms would be:
The error is prompted immediately after the script is run.
The script might have worked well in previous Python versions.
User Mixon's long epos about administrator execution privileges has no impact at all. There would be no access errors to the files mentioned in the code from the console or other pieces of software.
Solution:
Change the import line to "import tkinter" and add the namespace to tkinter methods in the code.
Two easy steps to follow:
Close the document which is used in your script if it's open in your PC
Run Spyder from the Windows menu as "Run as administrator"
Error resolved.
This error actually also comes when using keras.preprocessing.image so for example:
img = keras.preprocessing.image.load_img(folder_path, target_size=image_size)
will throw the permission error. Strangely enough though, the problem is solved if you first import the library: from keras.preprocessing import image and only then use it. Like so:
img = image.load_img(img_path, target_size=(180,180))

Categories