Python中確定目錄是否對執行腳本的用戶可寫的最佳方式是什麼?由於這可能涉及使用os模塊,我應該提到我正在* nix環境下運行它。確定目錄是否可寫
確定目錄是否可寫
回答
它可能看起來很奇怪表明這一點,但一個共同的Python的成語是
它更容易請求原諒 比許可
繼習語,人們可能會說:
嘗試寫入有問題的目錄,並在沒有權限的情況下捕獲錯誤。
檢查模式位:
def isWritable(name):
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)
)
此解決方案僅適用於Unix。 – 2013-09-26 15:00:07
雖然什麼克里斯托夫認爲是更Python的解決方案,操作系統模塊確實有the os.access function檢查訪問:
os.access('/path/to/folder', os.W_OK)
#W_OK是寫作,R_OK閱讀等
根據情況,「容易請求原諒」並不是最好的方式,即使在Python中也是如此。有時候可以像上面提到的os.access()方法那樣「詢問權限」,例如當發生錯誤的概率很高時。 – mjv 2010-02-06 19:32:57
如果要將文件寫入目錄,僅測試寫入位是不夠的。如果要寫入目錄,則還需要測試執行位。 os.access('/ path/to/folder',os.W_OK | os.X_OK)os.W_OK本身只能刪除目錄(只有當該目錄爲空時) – fthinker 2012-03-23 17:13:14
os.access的另一個問題()'是否使用* real * UID和GID進行檢查,而不是* *有效*進行檢查。這可能會導致SUID/SGID環境中的怪異現象。 ('但腳本運行setuid root,爲什麼不能寫入文件?') – Alexios 2016-05-13 08:37:28
如果你只關心文件權限,os.access(path, os.W_OK)
應該做你所要求的。如果您想知道您是否可以可以寫入目錄open()
用於寫入的測試文件(它不應該事先存在),請捕獲並檢查任何IOError
,然後清理測試文件。
更一般地說,爲了避免TOCTOU攻擊(如果腳本以提升的權限運行 - suid或cgi等),您不應該真正相信這些提前測試,但可以刪除priv,do open()
,並期望IOError
。
這裏是我創建基於ChristopheD的回答是:
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"
跨越這個線程搜索某人的例子絆倒了。在Google上的第一個結果,恭喜!
人們談論Pythonic在這個線程中做的方式,但沒有簡單的代碼示例?在這裏,你走了,因爲其他人誰在跌倒:
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")
這種嘗試打開用於寫入的文件句柄,並以一個錯誤退出,如果指定的文件無法寫入:這是更容易閱讀,是一個更好的方式,而不是在文件路徑或目錄上進行預先檢查,因爲它避免了競爭條件;在運行預選檢查時間以及實際嘗試寫入文件時,文件變得不可寫入的情況。
這適用於文件,而不是OP所要求的目錄。您可以在目錄中擁有一個文件,並且該目錄不可寫,但文件本身(如果該文件已存在)。這對於系統管理很重要,例如,您可以創建想要存在的日誌文件,但不希望人們將日誌目錄用於臨時空間。 – 2017-04-11 18:41:41
......實際上我把它投下來了,我現在認爲這是一個錯誤。正如Rohaq所提到的,有些問題與競賽條件有關。在可以測試目錄的各種平臺上還有其他問題,它看起來是可寫的,但實際上並不是這樣。執行跨平臺目錄可寫檢查比看起來更難。所以只要你意識到這些問題,這可能是一個很好的技術。我從UNIX-Y的角度來看待它,這是我的錯誤。有人編輯這個答案,所以我可以刪除我的-1。 – 2017-04-12 15:29:01
我編輯它,以防你想刪除-1 :) 是的,跨平臺目錄檢查可能會變得更加複雜,但通常你正在尋找創建/寫入該目錄中的文件 - 在這種情況下,我給出的示例仍然適用。如果出現一些與目錄權限相關的問題,它在嘗試打開文件句柄時仍應該拋出IOError。 – Rohaq 2017-04-22 04:13:44
使用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
我認爲使用tempfile的人更清潔,因爲它肯定不會留下殘留物。 – grasshopper 2014-12-31 00:59:06
此方法不能使用'tempfile'。它只在沒有'OSError'意味着它有寫/刪除權限時才起作用。否則它不會返回False,因爲沒有返回錯誤,並且腳本不會繼續執行或退出。什麼都沒有返回。它只是停留在那條線上。然而,創建非臨時文件(如khattam的答案)在允許或拒絕權限時都有效。幫幫我? – 2016-05-06 18:24:27
if os.access(path_to_folder, os.W_OK) is not True:
print("Folder not writable")
else :
print("Folder writable")
有關訪問的詳細信息,可以發現它here
這基本上是一個Max Shawabkeh的答案和一個小包裝的副本。使其成爲快速複製粘貼,但更好的主意是將其添加到Max的原始帖子。 – 2017-08-20 18:21:52
如果您需要檢查的另一個用戶許可(是的,我意識到這個矛盾的問題,但可能會派上用場),你可以通過pwd
模塊和目錄的模式位來完成。
免責聲明 - 在Windows上不起作用,因爲它不使用POSIX權限模型(並且pwd
模塊在那裏不可用),例如, - 僅適用於* nix系統的解決方案。
請注意,目錄必須設置所有3位 - 讀,寫和執行。
好的,R不是絕對必須的,但是無法列出目錄中的條目(所以你必須知道它們的名字)。另一方面的執行是絕對需要的 - 沒有用戶無法讀取文件的inode;所以即使有W,沒有X文件也不能被創建或修改。 More detailed explanation at this link.
最後,這些模式在stat
模塊中可用,它們的descriptions are in 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
- 1. 如何確定請求的目錄是否可寫?
- 2. 如何確定安裝目錄是否具有寫入權限
- 3. 是否可以確定另一個進程的工作目錄?
- 4. 確定兩個目錄名是否指向同一目錄
- 5. 確定是否點可見
- 6. 確定WindowServer是否可用?
- 7. 確定FTP URL是否是目錄名或使用C#
- 8. 確定NSString中的路徑是否是目錄或文件?
- 9. 在將root重寫到該目錄後,是否可以「隱藏」子目錄?
- 10. Log4J - 確定記錄器是否無法寫入文件系統
- 11. Android可繪製目錄是否可以包含子目錄?
- 12. 如何檢查是否可以將文件寫入目錄?
- 13. 如何使用Delphi來測試目錄是否可寫?
- 14. 如何檢查目錄是否可以在PHP中寫入?
- 15. 檢查是否每個人都可以讀取/寫入目錄
- 16. 如何檢查目錄是否可以被UID寫入?
- 17. 是否有可能確定.NET程序集編寫的語言?
- 18. 如何確定一個目錄是否在同一分區
- 19. 確定目錄是否已經存在使用SVN ANT
- 20. 如何確定路徑是否在目錄中? (POSIX)
- 21. Wix Howto確定安裝過程中是否存在目錄?
- 22. 如何確定一個目錄路徑是否被隱藏
- 23. 使用node.js來確定是否在git目錄中
- 24. 確定目錄是否在git控制下
- 25. 檢查目錄是否可讀
- 26. 我的目錄是否可執行?
- 27. 是否可以移動App_Data目錄?
- 28. 測試目錄是否可瀏覽
- 29. 是否可以確定UIImage是否可伸縮?
- 30. 基於默認目錄確定目錄
+1 Python或沒有,這是真的來測試訪問的最可靠方法。 – 2010-01-21 22:32:32
這還處理寫入磁盤時可能發生的其他錯誤 - 例如,沒有剩餘磁盤空間。這是努力的力量..你不需要記住一切可能出錯;-) – 2010-01-21 23:37:57
謝謝你們。由於速度是我在這裏做的事情的一個重要因素,所以決定和os.access一起去,儘管我當然可以理解「請求寬恕比容許更容易」的優點。 ;) – illuminatedtiger 2010-01-22 01:04:26