Skrypt konwertujący oktalne wartości uprawnień dostępu do plików na symboliczne wartości uprawnienień dostępu do plików UNIX

0

Cześć wszystkim

Napisałem na szybko skrypt wypisujący uprawnienia dostępu do plików w wylistowanym katalogu. Taki skrypt potrzebny mi jest do większego projektu, który udostępnia funkcję listowania katalogu i chciałbym żeby to listowanie było podobne do tego co jest w systemach typu UNIX, nie chcę na sucho tylko wypisywać plików.

Oto mój skrypt realizujący to co opisałem powyżej:

#!/usr/bin/python3

import os

def get_octal_permissions():
	files_permissions = []
	files = os.listdir('.')
	for f in files:
		file_permission = oct(os.stat(f).st_mode)[-3:]
		files_permissions.append(file_permission)
	return files_permissions

def get_symbolic_permissions(files_permissions):
	access_dict = {
		'0': '---',
		'1': '--x',
		'2': '-w-',
		'4': 'r--',
		'5': 'r-x',
		'6': 'rw-',
		'7': 'rwx'
	}
	
	all_perms = []
		
	for file_permission in files_permissions:
		roles = list(file_permission)
		for role in roles:
			perm = access_dict.get(role)
			all_perms.append(perm)
		print(''.join(all_perms))
		all_perms.clear()

if __name__ == '__main__':
	files_permissions = get_octal_permissions()
	get_symbolic_permissions(files_permissions)
	

Moje pytanie: Czy da się ten skrypt napisać jakoś krócej i lepiej?

1

Jest tu jeszcze kilka błędów związanych z zabezpieczeniem programu przed wysypywaniem - które na przykład u mnie występują.
Po zeskanowaniu ścieżki listdir'em, pliki ukryte (w unix'ie - od kropki) oraz katalogi, przy próbie odczytu przez stat, wyrzucają FileNotFoundError.
Sprawdź czy występuje to także u ciebie :).

Następny błąd, to już czysto strukturalny.

        '2': '-w-',
        '4': 'r--',

Brakuje ci tu opcji '3': '-wx'. Co znowu może się objawić w różny sposób, przesunięciem/błędem etc.

Poza tym nic szczególnie wysypującego się nie widzę.

Do samych funkcji, mogę jedynie wyrazić swoją opinię, że tej pierwszej 'get_octal_permission' brakuje argumentu którym by była aktualnie nam potrzebna ścieżka, bezargumentowo może być '.' ale zakładając że może być przydatne czytanie względne/bezwzględne w innym miejscu programu, można to zrobić jako keyword argument, zwiększy to elastyczność funkcji.
Np. def get_octal_permission(path = '.'):

0
Guaz napisał(a):

Jest tu jeszcze kilka błędów związanych z zabezpieczeniem programu przed wysypywaniem - które na przykład u mnie występują.
Po zeskanowaniu ścieżki listdir'em, pliki ukryte (w unix'ie - od kropki) oraz katalogi, przy próbie odczytu przez stat, wyrzucają FileNotFoundError.
Sprawdź czy występuje to także u ciebie :).

Następny błąd, to już czysto strukturalny.

        '2': '-w-',
        '4': 'r--',

Brakuje ci tu opcji '3': '-wx'. Co znowu może się objawić w różny sposób, przesunięciem/błędem etc.

Poza tym nic szczególnie wysypującego się nie widzę.

Do samych funkcji, mogę jedynie wyrazić swoją opinię, że tej pierwszej 'get_octal_permission' brakuje argumentu którym by była aktualnie nam potrzebna ścieżka, bezargumentowo może być '.' ale zakładając że może być przydatne czytanie względne/bezwzględne w innym miejscu programu, można to zrobić jako keyword argument, zwiększy to elastyczność funkcji.
Np. def get_octal_permission(path = '.'):

Dzięki bardzo za odpowiedź. Ten skrypt był pisany naprawdę na szybko i nie zwracałem większej uwagi na szczegóły zapewne gdy wdrażałbym go już do projektu to zwróciłbym na nie uwagę. Chodziło mi bardziej o to czy ten skrypt można napisać jakoś krócej i może sprytniej, np. z przesunięciem bitów. Chciałbym żeby ta funkcjonalność programu była w miarę jak najkrótsza.

Edit: Przy czym błąd z podaniem ścieżki w pierwszej metodzie jest jak najbardziej do wytknięcia, ponieważ nawet w formie testowej mogłem tę ścieżkę rzeczywiście podać tam jako parametr. :) Co do pierwszego błędu z FileNotFoundError to rzeczywiście on występuje też u mnie w niektórych katalogach, na razie nie mam pomysłu jak ten problem rozwiązać.

0

Problem z FileNotFoundError został przeze mnie rozwiązany. Gdyby ktoś kiedyś potrzebował podobny skrypt to rozwiązanie jest takie:

#!/usr/bin/python3

import os

def get_octal_permissions(path):
	files_permissions = []
	files = os.listdir(path)
	for f in files:
		file_permission = oct(os.stat(path + '/' + f).st_mode)[-3:]
		files_permissions.append(file_permission)
	return files_permissions

def get_symbolic_permissions(files_permissions):
	access_dict = {
		'0': '---',
		'1': '--x',
		'2': '-w-',
		'3': '-wx',
		'4': 'r--',
		'5': 'r-x',
		'6': 'rw-',
		'7': 'rwx'
	}
	
	all_perms = []
		
	for file_permission in files_permissions:
		roles = list(file_permission)
		for role in roles:
			perm = access_dict.get(role)
			all_perms.append(perm)
		print(''.join(all_perms))
		all_perms.clear()

if __name__ == '__main__':
	files_permissions = get_octal_permissions('/home/shizzer')
	get_symbolic_permissions(files_permissions)

W tym miejscu zamiast samego pliku należy podać całą ścieżkę żeby metoda os.stat wiedziała gdzie się ten plik dokładnie znajduje. Ścieżki nie trzeba podawać jedynie w przypadku gdy wypisujemy zawartość katalogu, w którym umieszczony jest sam skrypt:

file_permission = oct(os.stat(path + '/' + f).st_mode)[-3:]
1
>>> files_permissions = ['777', '543', '321']
>>> access_dict = { '0':'---','1': '--x','2': '-w-','3': '-wx','4': 'r--','5': '
r-x','6': 'rw-','7': 'rwx'}
>>> #all_perms = [] @Edit ta linia niepotrzebna*
>>> for file_permission in files_permissions:
...     all_perms = ''.join(access_dict.get(digit) for digit in file_permission)
...     print(all_perms)
... 
rwxrwxrwx
r-xr---wx
-wx-w---x

W sumie to prosty generator rozwiąże kilka linijek kodu, zapewne szybciej przez brak konwersji stringa na oddzielne litery umieszczone w strukturze listy.
Przykład na jakiej zasadzie to działa:

>>> [a+'x' for a in 'abc']
['ax', 'bx', 'cx']
1

n = int(n)
''.join('-xw r'[n & i] for i in [4,2,1])

Takie coś zamiast słownika powinno zadziałać.

Sorry za brak tagów, ale na telefonie nie mam ich na klawiaturze.

1 użytkowników online, w tym zalogowanych: 0, gości: 1