স্ক্রিপ্টটি সম্পাদনকারী ব্যবহারকারীর জন্য কোনও ডিরেক্টরি লেখার যোগ্য কিনা তা নির্ধারণ করার জন্য পাইথনের সর্বোত্তম উপায় কী হবে? যেহেতু এটি সম্ভবত ওএস মডিউলটি ব্যবহারের সাথে জড়িত থাকবে আমার উল্লেখ করা উচিত আমি এটি * নিক্স পরিবেশের অধীনে চালাচ্ছি।
স্ক্রিপ্টটি সম্পাদনকারী ব্যবহারকারীর জন্য কোনও ডিরেক্টরি লেখার যোগ্য কিনা তা নির্ধারণ করার জন্য পাইথনের সর্বোত্তম উপায় কী হবে? যেহেতু এটি সম্ভবত ওএস মডিউলটি ব্যবহারের সাথে জড়িত থাকবে আমার উল্লেখ করা উচিত আমি এটি * নিক্স পরিবেশের অধীনে চালাচ্ছি।
উত্তর:
যদিও ক্রিস্টোফের পরামর্শ যা আরও পাইথোনিক সমাধান, ওস মডিউলে অ্যাসেস চেক করার জন্য os.access ফাংশন রয়েছে :
os.access('/path/to/folder', os.W_OK)
# ডাব্লু_ওকে লেখার জন্য, আর_ওকে পড়ার জন্য ইত্যাদি is
os.access()
এটি ব্যবহার চেক হয় বাস্তব ইউআইডি ও gid না কার্যকর বেশী। এটি SID / SGID পরিবেশে অদ্ভুততার কারণ হতে পারে। ('তবে স্ক্রিপ্টটি নির্ধারিত মূলটি চালায়, কেন এটি ফাইলটিতে লিখতে পারে না?')
os.access(dirpath, os.W_OK | os.X_OK)
আমার লেখার অ্যাক্সেস না থাকলেও সত্য ফিরে আসে।
এটির পরামর্শ দেওয়া অদ্ভুত মনে হতে পারে তবে একটি সাধারণ পাইথন আইডিয়াম
অনুমতি চেয়ে ক্ষমা চাইতে আরও সহজ
এই মূর্তি অনুসরণ করে, কেউ বলতে পারে:
প্রশ্নে ডিরেক্টরিটিতে লেখার চেষ্টা করুন, এবং যদি আপনার কাছে অনুমতি দেওয়ার অনুমতি না থাকে তবে ত্রুটিটি ধরুন।
except: pass
- এইভাবে আপনি সর্বদা আশাবাদী হতে পারেন এবং নিজেকে নিয়ে অত্যন্ত চিন্তা করতে পারেন। / বিদ্রূপ বন্ধ। এখন আমি কেন, উদাহরণস্বরূপ আমার ফাইল সিস্টেমের প্রতিটি ডিরেক্টরিতে কিছু লেখার চেষ্টা করতে চাইছি, লেখার যোগ্য লোকেশনগুলির একটি তালিকা তৈরি করতে?
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
আপডেট: উইন্ডোজে আবার কোডটি পরীক্ষা করার পরে আমি দেখতে পাচ্ছি যে সেখানে টেম্পাইল ব্যবহার করার সময় আসলেই একটি সমস্যা আছে, ইস্যু 22107 দেখুন : টেম্পাইল মডিউলটি উইন্ডোজটিতে অ্যাক্সেস প্রত্যাখ্যান ত্রুটির ভুল ব্যাখ্যা করে । অ-লিখনযোগ্য ডিরেক্টরির ক্ষেত্রে, কোডটি বেশ কয়েক সেকেন্ডের জন্য স্তব্ধ হয়ে থাকে এবং অবশেষে একটি নিক্ষেপ করে 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
বিলম্ব অবশ্যই এখনও এই ক্ষেত্রে উপস্থিত।
tempfile
। এটি তখনই কাজ করে যখন এর কোনও OSError
অর্থ নেই যেখানে এটি লেখার / মুছার অনুমতি রয়েছে। অন্যথায় এটি return False
ত্রুটি ফিরে না পাওয়ার কারণ হবে না এবং স্ক্রিপ্টটি চালানো বা প্রস্থান করা চালিয়ে যাবে না। কিছুই ফিরিয়ে দেওয়া হয় না। এটা ঠিক যে লাইনে আটকে আছে। যাইহোক, খাত্তমের উত্তর হিসাবে অস্থায়ী ফাইল তৈরি করা যখন অনুমতি অনুমোদিত বা অস্বীকৃত হয় উভয়ই কার্যকর হয়। সাহায্য?
OSError: [Errno 30] Read-only file system
কারও জন্য উদাহরণ অনুসন্ধান করে এই থ্রেড জুড়ে হোঁচট খেয়েছে। গুগলে প্রথম ফলাফল, সম্মিলিত!
লোকেরা এই থ্রেডে পাইথনিক পদ্ধতিতে কাজ করার বিষয়ে কথা বলে, তবে কোনও সাধারণ কোড উদাহরণ নেই? অন্য যে কেউ হোঁচট খায় তার জন্য আপনি এখানে যান:
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")
এটি লেখার জন্য একটি ফাইলহ্যান্ডল খোলার চেষ্টা করে এবং নির্দিষ্ট ফাইলটিতে লিখিত না লিখলে একটি ত্রুটি থেকে বেরিয়ে যায়: এটি পড়ার পক্ষে এটি আরও সহজ এবং ফাইল পাথ বা ডিরেক্টরিতে প্রাক-পরীক্ষা করার চেয়ে এটি করার আরও ভাল উপায় , কারণ এটি বর্ণের পরিস্থিতি এড়িয়ে চলে; আপনি যখন প্রিচেক চালাবেন সেই সময়ের মধ্যে এবং যখন আপনি আসলে ফাইলটিতে লেখার চেষ্টা করছেন তখন ফাইলটি লিখনযোগ্য হয়ে যায় cases
যদি আপনি কেবল ফাইল পারমস সম্পর্কে যত্নশীল হন তবে os.access(path, os.W_OK)
আপনার যা চান তা করা উচিত। আপনি যদি এর পরিবর্তে জানেন যে কিনা আপনি যদি চান করতে পারেন , ডিরেক্টরি লিখতে open()
(এটা পূর্বেই উপস্থিত হওয়া উচিত নয়) লেখার জন্য একটি পরীক্ষা ফাইল, ধরা ও কোনো পরীক্ষা IOError
, এবং পরে পরীক্ষা ফাইল পরিষ্কার।
আরও সাধারণভাবে, টেকটিউ আক্রমণগুলি এড়াতে (কেবলমাত্র যদি আপনার স্ক্রিপ্টটি উন্নত সুবিধাগুলি - মামলা বা সিজি বা তাই নিয়ে চালিত হয়) তবে আপনার সত্যিকারের এই পরীক্ষাগুলি সত্যই বিশ্বাস করা উচিত নয়, তবে প্রাইভেস ড্রপ করুন open()
, করুন এবং আশা করুন IOError
।
মোড বিট পরীক্ষা করুন:
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)
)
ক্রিস্টোফিডের উত্তরের ভিত্তিতে আমি এখানে কিছু তৈরি করেছি:
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")
অ্যাক্সেস সম্পর্কে আরও তথ্য এটি এখানে খুঁজে পেতে পারেন
আরগপার্সের মাধ্যমে যুক্তি যুক্ত করার সময় আমি একই প্রয়োজনে ছুটে এসেছি। বিল্ট ইন type=FileType('w')
আমার পক্ষে কাজ করবে না কারণ আমি একটি ডিরেক্টরি খুঁজছিলাম। আমার সমস্যাটি সমাধান করার জন্য আমি নিজের পদ্ধতিটি লিখে শেষ করেছি। এখানে আরগপার্স স্নিপেটের ফলাফল।
#! /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 ~
আমি ফিরে গিয়ে প্রিন্ট opts.dir প্রান্তে যুক্ত করেছি এবং সমস্ত কিছু পছন্দসই হিসাবে কাজ করছে বলে মনে হচ্ছে।
আপনার যদি অন্য ব্যবহারকারীর অনুমতি পরীক্ষা করতে হয় (হ্যাঁ, আমি বুঝতে পারি যে এটি প্রশ্নের বিপরীতমুখী, তবে কারও পক্ষে কার্যকর হতে পারে), আপনি এটি pwd
মডিউল এবং ডিরেক্টরিটির মোড বিটের মাধ্যমে করতে পারেন ।
দাবি অস্বীকার - উইন্ডোজে কাজ করে না, কারণ এটি পসিক্স অনুমতিগুলির মডেল ব্যবহার করে না (এবং pwd
মডিউলটি সেখানে উপলব্ধ নেই), যেমন - সমাধান কেবল * নিক্স সিস্টেমের জন্য।
মনে রাখবেন যে একটি ডিরেক্টরিতে 3 টি বিট সেট থাকতে হবে - পড়ুন, লিখুন এবং এক্সেক্সট করুন।
ঠিক আছে, আর একটি নিখুঁত আবশ্যক নয়, তবে ডাব্লু / ও এটি আপনি ডিরেক্টরিতে প্রবেশের তালিকাটি তালিকাভুক্ত করতে পারবেন না (যাতে আপনার নামগুলি জানতে হবে)। অন্যদিকে এক্সিকিউট করা একেবারে প্রয়োজন - ডাব্লু / ও এটি ব্যবহারকারী ফাইলের ইনোডগুলি পড়তে পারে না; সুতরাং, এক্স ফাইল ছাড়াই ডাব্লু থাকাও তৈরি বা সংশোধন করা যায় না। এই লিঙ্কে আরও বিস্তারিত ব্যাখ্যা।
অবশেষে, মোডগুলিতে stat
মডিউল পাওয়া যায় , তাদের বিবরণগুলি ইনোড (7) ম্যানে রয়েছে ।
নমুনা কোড কীভাবে চেক করবেন:
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