Jaki byłby najlepszy sposób w Pythonie na określenie, czy katalog jest zapisywalny dla użytkownika wykonującego skrypt? Ponieważ prawdopodobnie będzie to wymagało użycia modułu os, powinienem wspomnieć, że uruchamiam go w środowisku * nix.
python
file
permissions
directory
operating-system
podświetlany tygrys
źródło
źródło
os.access()
jest to, że sprawdza przy użyciu prawdziwego UID i GID, a nie skutecznych . Może to powodować dziwności w środowiskach SUID / SGID. („ale skrypt uruchamia setuid root, dlaczego nie może zapisywać do pliku?”)os.access(dirpath, os.W_OK | os.X_OK)
zwraca True, nawet jeśli nie mam dostępu do zapisu.Sugerowanie tego może wydawać się dziwne, ale powszechnym idiomem w Pythonie jest
Idąc za tym idiomem, można by powiedzieć:
Spróbuj napisać do odpowiedniego katalogu i wyłap błąd, jeśli nie masz do tego uprawnień.
źródło
except: pass
- w ten sposób zawsze możesz być optymistą i dobrze o sobie myśleć. / sarkazm wyłączony. Dlaczego miałbym chcieć, na przykład, spróbować zapisać coś w każdym katalogu w moim systemie plików, aby utworzyć listę zapisywalnych lokalizacji?Moje rozwiązanie z wykorzystaniem
tempfile
modułu:Aktualizacja: po ponownym przetestowaniu kodu w systemie Windows widzę, że rzeczywiście występuje problem podczas używania tam pliku tymczasowego, zobacz problem22107: moduł tymczasowego pliku błędnie interpretuje błąd odmowy dostępu w systemie Windows . W przypadku katalogu, którego nie można zapisać, kod zawiesza się na kilka sekund, a na koniec generuje plik
IOError: [Errno 17] No usable temporary file name found
. Może to właśnie obserwował użytkownik2171842? Niestety problem nie został na razie rozwiązany, więc aby sobie z tym poradzić, należy również wyłapać błąd:Oczywiście w takich przypadkach opóźnienie nadal występuje.
źródło
tempfile
. działa tylko wtedy, gdy nie maOSError
znaczenia, że ma uprawnienia do zapisu / usuwania. w przeciwnym razie tak się nie stanie,return False
ponieważ nie zostanie zwrócony żaden błąd, a skrypt nie będzie kontynuował wykonywania ani kończy pracy. nic nie jest zwracane. po prostu utknął na tej linii. Jednak utworzenie pliku nie tymczasowego, takiego jak odpowiedź khattam, działa zarówno wtedy, gdy zezwolenie jest dozwolone, jak i nie. Wsparcie?Natknąłem się na ten wątek, szukając przykładów dla kogoś. Pierwszy wynik w Google, gratulacje!
W tym wątku ludzie mówią o sposobie robienia tego w Pythonie, ale nie ma prostych przykładów kodu? Proszę bardzo, dla każdego, kto się potknie:
To próbuje otworzyć uchwyt pliku do zapisu i kończy pracę z błędem, jeśli określony plik nie może zostać zapisany: Jest to o wiele łatwiejsze do odczytania i jest o wiele lepszym sposobem zrobienia tego niż wykonywanie wstępnych kontroli ścieżki pliku lub katalogu ponieważ unika warunków wyścigu; przypadki, w których plik staje się niemożliwy do zapisu między momentem uruchomienia kontroli wstępnej a faktyczną próbą zapisu do pliku.
źródło
Jeśli zależy Ci tylko na uprawnieniach do pliku,
os.access(path, os.W_OK)
powinieneś zrobić to, o co prosisz. Jeśli natomiast chcemy wiedzieć, czy można zapisywać do kataloguopen()
plik testowy na piśmie (nie powinien istnieć wcześniej), złapać i zbadać każdyIOError
, i oczyścić plik testowy później.Mówiąc bardziej ogólnie, aby uniknąć ataków TOCTOU (tylko problem, jeśli twój skrypt działa z podwyższonymi uprawnieniami - suid lub cgi lub coś podobnego), nie powinieneś naprawdę ufać tym testom z wyprzedzeniem, ale porzuć uprawnienia, zrób
open()
i oczekuj theIOError
.źródło
Sprawdź bity trybu:
źródło
Oto coś, co stworzyłem na podstawie odpowiedzi ChristopheDa:
źródło
więcej informacji o dostępie można znaleźć tutaj
źródło
Napotkałem tę samą potrzebę, dodając argument za pośrednictwem argparse. Wbudowany
type=FileType('w')
nie działałby dla mnie, ponieważ szukałem katalogu. Skończyło się na napisaniu własnej metody rozwiązania mojego problemu. Oto wynik z argparse snippet.Z tego wynika:
Wróciłem i na końcu dodałem print opts.dir i wszystko wydaje się działać zgodnie z oczekiwaniami.
źródło
Jeśli chcesz sprawdzić uprawnienia innego użytkownika (tak, zdaję sobie sprawę, że przeczy to pytaniu, ale może się komuś przydać), możesz to zrobić przez
pwd
moduł i bity trybu katalogu.Disclaimer - nie działa na Windows, ponieważ nie korzysta z modelu uprawnień POSIX (a
pwd
moduł nie jest tam dostępny), np. - rozwiązanie tylko dla systemów * nix.Zauważ, że katalog musi mieć ustawione wszystkie 3 bity - odczyt, zapis i eXecute.
Ok, R nie jest absolutną koniecznością, ale bez niego nie możesz wyświetlić listy wpisów w katalogu (więc musisz znać ich nazwy). Z drugiej strony wykonanie jest absolutnie potrzebne - bez niego użytkownik nie może odczytać i-węzłów pliku; więc nawet mając W, bez plików X nie można tworzyć ani modyfikować. Bardziej szczegółowe wyjaśnienie pod tym linkiem.
Wreszcie tryby są dostępne w
stat
module, ich opisy znajdują się w inode (7) man .Przykładowy kod jak sprawdzić:
źródło