디렉토리의 쓰기 가능 여부 결정
Python에서 스크립트를 실행하는 사용자가 디렉토리를 쓸 수 있는지 여부를 결정하는 가장 좋은 방법은 무엇입니까?OS 모듈을 사용해야 하기 때문에 *nix 환경에서 실행하고 있습니다.
Christophe가 제안한 것은 좀 더 Pythonic 솔루션이지만, OS 모듈에는 액세스를 확인하는 os.access 기능이 있습니다.
os.access('/path/to/folder', os.W_OK)
W_OK는 쓰기, R_OK는 읽기 등입니다.
이것을 제안하는 것은 이상해 보일 수 있지만, 일반적인 파이썬 관용구는
용서를 구하는 것이 허락을 구하는 것보다 쉽습니다.
그 관용구를 따라서, 누군가는 다음과 같이 말할 수 있습니다.
해당 디렉터리에 기록해 보고 권한이 없는 경우 오류를 확인합니다.
를 사용하는 내 솔루션tempfile
모듈:
import tempfile
import errno
def isWritable(path):
try:
testfile = tempfile.TemporaryFile(dir = path)
testfile.close()
except OSError as e:
if e.errno == errno.EACCES: # 13
return False
e.filename = path
raise
return True
업데이트: Windows에서 코드를 다시 테스트한 결과, 문제 22107: tempfile 모듈이 Windows에서 액세스 거부 오류를 잘못 해석합니다.쓰기 불가능한 디렉터리의 경우 코드가 몇 초 동안 중단되고 마지막으로 다음을 던집니다.IOError: [Errno 17] No usable temporary file name found
이것이 2171842 사용자가 관찰한 것일 수도 있습니다.유감스럽게도 현재 이 문제가 해결되지 않았기 때문에 이 문제를 해결하려면 다음과 같은 오류도 파악해야 합니다.
except (OSError, IOError) as e:
if e.errno == errno.EACCES or e.errno == errno.EEXIST: # 13, 17
물론 이 경우에도 지연은 여전히 존재합니다.
모드 비트를 확인합니다.
import os, stat
def isWritable(dirname):
uid = os.geteuid()
gid = os.getegid()
s = os.stat(dirname)
mode = s[stat.ST_MODE]
return (
((s[stat.ST_UID] == uid) and (mode & stat.S_IWUSR)) or
((s[stat.ST_GID] == gid) and (mode & stat.S_IWGRP)) or
(mode & stat.S_IWOTH)
)
파일 파마만 신경 쓴다면,os.access(path, os.W_OK)
당신이 요구하는 것을 해야 합니다.대신 디렉토리에 쓸 수 있는지 여부를 알고 싶다면,open()
쓰기 위한 테스트 파일(사전에 존재해서는 안 됨), 캡처 및 검사IOError
테스트 파일을 정리합니다.
더 일반적으로 TOCTO 공격(스크립트가 상승된 권한으로 실행되는 경우에만 문제)을 방지하려면 이러한 사전 테스트를 신뢰하지 말고 권한을 삭제하십시오.open()
그리고 기대합니다.IOError
.
누군가를 위한 예시를 찾다가 우연히 이 스레드를 발견했습니다.구글의 첫 번째 결과를 축하합니다!
사람들은 이 스레드에서 파이썬 방식에 대해 이야기하지만, 간단한 코드 예제는 없습니까?여기 있습니다. 다른 누구든 끼어들 수 있습니다.
import sys
filepath = 'C:\\path\\to\\your\\file.txt'
try:
filehandle = open( filepath, 'w' )
except IOError:
sys.exit( 'Unable to write to file ' + filepath )
filehandle.write("I am writing this text to the file\n")
이렇게 하면 쓰기 위해 파일 핸들을 열고 지정된 파일을 다음에 쓸 수 없는 경우 오류와 함께 종료됩니다.이것은 읽기가 훨씬 쉬우며 파일 경로나 디렉터리에서 사전 검사를 수행하는 것보다 훨씬 더 나은 방법입니다. 사전 검사를 실행할 때와 실제로 파일에 쓰기를 시도할 때 사이에 파일을 쓸 수 없게 되는 경우를 방지하기 때문입니다.
크리스토프 D의 답변을 바탕으로 제가 만든 것은 다음과 같습니다.
import os
def isWritable(directory):
try:
tmp_prefix = "write_tester";
count = 0
filename = os.path.join(directory, tmp_prefix)
while(os.path.exists(filename)):
filename = "{}.{}".format(os.path.join(directory, tmp_prefix),count)
count = count + 1
f = open(filename,"w")
f.close()
os.remove(filename)
return True
except Exception as e:
#print "{}".format(e)
return False
directory = "c:\\"
if (isWritable(directory)):
print "directory is writable"
else:
print "directory is not writable"
if os.access(path_to_folder, os.W_OK) is not True:
print("Folder not writable")
else :
print("Folder writable")
액세스에 대한 자세한 내용은 여기에서 확인할 수 있습니다.
저는 Argparse를 통해 논쟁을 추가하는 동안 이와 같은 필요성에 부딪혔습니다.에 된 것.type=FileType('w')
제가 디렉토리를 찾고 있었기 때문에 제게 도움이 되지 않았습니다.저는 결국 제 문제를 해결하기 위한 저만의 방법을 쓰게 되었습니다.다음은 Argparse 스니펫을 사용한 결과입니다.
#! /usr/bin/env python
import os
import argparse
def writable_dir(dir):
if os.access(dir, os.W_OK) and os.path.isdir(dir):
return os.path.abspath(dir)
else:
raise argparse.ArgumentTypeError(dir + " is not writable or does not exist.")
parser = argparse.ArgumentParser()
parser.add_argument("-d","--dir", type=writable_dir, default='/tmp/',
help="Directory to use. Default: /tmp")
opts = parser.parse_args()
이를 통해 다음과 같은 결과가 발생합니다.
$ python dir-test.py -h
usage: dir-test.py [-h] [-d DIR]
optional arguments:
-h, --help show this help message and exit
-d DIR, --dir DIR Directory to use. Default: /tmp
$ python dir-test.py -d /not/real
usage: dir-test.py [-h] [-d DIR]
dir-test.py: error: argument -d/--dir: /not/real is not writable or does not exist.
$ python dir-test.py -d ~
다시 돌아가서 printopt.dir를 끝에 추가했더니 모든 것이 원하는 대로 작동하는 것 같습니다.
다른 사용자의 권한을 확인해야 하는 경우(네, 질문과 모순된다는 것을 알고 있지만 누군가에게 유용할 수 있습니다), 를 통해 이 작업을 수행할 수 있습니다.pwd
모듈 및 디렉터리의 모드 비트.
고지 사항 - POSIX 권한 모델(및 )을 사용하지 않기 때문에 Windows에서는 작동하지 않습니다.pwd
모듈은 여기에서 사용할 수 없습니다. 예: *nix 시스템에만 해당되는 솔루션입니다.
디렉터리에는 읽기, 쓰기 및 eXecute의 3비트가 모두 설정되어 있어야 합니다.
예, R은 필수 항목은 아니지만, R이 없으면 디렉토리에 항목을 나열할 수 없습니다(따라서 이름을 알아야 함).반면에 실행은 절대적으로 필요합니다. 사용자가 파일의 inode를 읽을 수 없기 때문에 X 파일이 없는 W 파일도 만들거나 수정할 수 없습니다.자세한 설명은 이 링크를 참조하십시오.
는 마막으로, ▁the▁are로 사용할 수 .stat
모듈, 그들의 설명은 inode(7) man에 있습니다.
확인 방법 샘플 코드:
import pwd
import stat
import os
def check_user_dir(user, directory):
dir_stat = os.stat(directory)
user_id, group_id = pwd.getpwnam(user).pw_uid, pwd.getpwnam(user).pw_gid
directory_mode = dir_stat[stat.ST_MODE]
# use directory_mode as mask
if user_id == dir_stat[stat.ST_UID] and stat.S_IRWXU & directory_mode == stat.S_IRWXU: # owner and has RWX
return True
elif group_id == dir_stat[stat.ST_GID] and stat.S_IRWXG & directory_mode == stat.S_IRWXG: # in group & it has RWX
return True
elif stat.S_IRWXO & directory_mode == stat.S_IRWXO: # everyone has RWX
return True
# no permissions
return False
stat 개체가 읽을 수 있는지 또는 쓸 수 있는지 확인
파이프가 읽을 수 있는지 또는 쓸 수 있는지 확인하는 데 유용합니다.
import os, stat
def check_access(s, check="r"):
"check if s=os.stat(path) is readable or writable"
u = os.geteuid(); g = os.getegid(); m = s.st_mode
if check == "r":
return (
((s[stat.ST_UID] == u) and (m & stat.S_IRUSR)) or
((s[stat.ST_GID] == g) and (m & stat.S_IRGRP)) or
(m & stat.S_IROTH)
) != 0
if check == "w":
return (
((s[stat.ST_UID] == u) and (m & stat.S_IWUSR)) or
((s[stat.ST_GID] == g) and (m & stat.S_IWGRP)) or
(m & stat.S_IWOTH)
) != 0
s = os.stat(0) # fd 0 == stdin
print(f"fd 0 is readable?", check_access(s, "r"))
s = os.stat(1) # fd 1 == stdout
print(f"fd 1 is writable?", check_access(s, "w"))
os.write(1, b"hello\n")
Joe Koberg의 답변에.
참고 항목: Javascript에서도 동일한 항목
아마도 창문이 깨졌을 것입니다.
언급URL : https://stackoverflow.com/questions/2113427/determining-whether-a-directory-is-writeable
'programing' 카테고리의 다른 글
jquery ID(공백 포함) (0) | 2023.08.05 |
---|---|
Axios 400 오류 요청 콜 대신에 호출합니다. (0) | 2023.08.05 |
'Run With PowerShell'을 사용하여 실행할 때 다른 스크립트에서 함수 호출 (0) | 2023.08.05 |
버튼 배경이 투명함 (0) | 2023.08.05 |
Android View에 해당하는 iOS.GONE 가시성 모드 (0) | 2023.08.05 |