To nieco egzotyczne pytanie, ale wydaje się, że w sieci nie ma dużo informacji na ten temat. Właśnie dodałem odpowiedź na pytanie dotyczące zewnętrznego atrybutu pliku formatu zip . Jak widać z mojej odpowiedzi, dochodzę do wniosku, że tylko drugi bajt (z 4 bajtów) jest faktycznie używany dla Uniksa. Najwyraźniej zawiera to wystarczającą ilość informacji podczas rozpakowywania, aby wywnioskować, czy obiekt jest plikiem, czy katalogiem, a także ma miejsce na inne informacje o uprawnieniach i atrybutach. Moje pytanie brzmi: w jaki sposób mapuje się to na zwykłe uprawnienia Unix? Czy zwykłe uprawnienia uniksowe (np. Poniżej), które ls
pasują do dokładnie jednego bajtu, a jeśli tak, czy ktoś może opisać układ lub podać odniesienie, proszę?
$ ls -la
total 36
drwxr-xr-x 3 faheem faheem 4096 Jun 10 01:11 .
drwxrwxrwt 136 root root 28672 Jun 10 01:07 ..
-rw-r--r-- 1 faheem faheem 0 Jun 10 01:07 a
drwxr-xr-x 2 faheem faheem 4096 Jun 10 01:07 b
lrwxrwxrwx 1 faheem faheem 1 Jun 10 01:11 c -> b
Pozwólcie, że uściślę to, zadając konkretne pytanie. Zgodnie z cytowaną w mojej odpowiedzi łatką Trac możesz utworzyć plik zip z fragmentem kodu Pythona poniżej.
040755 << 16L
Wartość odpowiada utworzenia pustego katalogu z uprawnieniami drwxr-xr-x
. (Przetestowałem to). Wiem, że 0755
odpowiada rwxr-xr-x
wzorowi, ale co z tym 04
i jak cała wartość odpowiada bajtowi? Zauważyłem również, że << 16L
odpowiada bitowe przesunięcie w lewo o 16 miejsc, co sprawiłoby, że skończyłoby to na drugim miejscu od górnego bajtu.
def makezip1():
import zipfile
z = zipfile.ZipFile("foo.zip", mode = 'w')
zfi = zipfile.ZipInfo("foo/empty/")
zfi.external_attr = 040755 << 16L # permissions drwxr-xr-x
z.writestr(zfi, "")
print z.namelist()
z.close()
EDYCJA: Po ponownym przeczytaniu tego, uważam, że mój wniosek, że uprawnienia Unix odpowiadają tylko jednemu bajtowi, może być niepoprawny, ale pozwolę powyższemu zastąpić teraźniejszość, ponieważ nie jestem pewien, jaka jest prawidłowa odpowiedź.
EDYCJA 2: Rzeczywiście, myliłem się co do wartości uniksowych odpowiadających tylko 1 bajtowi. Jak wyjaśniono w @ Random832, wykorzystuje on dwa górne dwa bajty. Na odpowiedź @ Random832 możemy skonstruować pożądaną 040755
wartość z tabel, które podaje poniżej. Mianowicie:
__S_IFDIR + S_IRUSR + S_IWUSR + S_IXUSR + S_IRGRP + S_IXGRP + S_IROTH + S_IXOTH
0040000 + 0400 + 0200 + 0100 + 0040 + 0010 + 0004 + 0001
= 40755
Dodatek znajduje się tutaj w bazie 8 .
Odpowiedzi:
0040000
to tradycyjna wartośćS_IFDIR
flagi typu pliku reprezentującej katalog. Typ wykorzystuje 4 górne bity 16-bitowejst_mode
wartości,0100000
jest wartością dla zwykłych plików.Wysokie 16 bitów atrybutów pliku zewnętrznego wydaje się być używanych do uprawnień specyficznych dla systemu operacyjnego. Wartości uniksowe są takie same jak w tradycyjnych implementacjach uniksowych. Inne systemy operacyjne używają innych wartości. Informacje na temat formatów używanych w różnych systemach operacyjnych można znaleźć w kodzie źródłowym Info-ZIP ( pobierz lub np. W debian
apt-get source [zip or unzip]
) - odpowiednie pliki sązipinfo.c
wunzip
, a pliki specyficzne dla platformyzip
.Są one konwencjonalnie zdefiniowane w liczbie ósemkowej (podstawa 8); jest to reprezentowane w C i python przez poprzedzenie liczby znakiem
0
.Wszystkie te wartości można znaleźć w
<sys/stat.h>
- link do wersji 4.4BSD . Nie ma ich w standardzie POSIX (który zamiast tego definiuje makra testowe); ale pochodzą z AT&T Unix i BSD. (w GNU libc / Linux same wartości są zdefiniowane jako__S_IFDIR
etc inbits/stat.h
, chociaż nagłówek jądra może być łatwiejszy do odczytania - wszystkie są wszędzie takie same).I oczywiście pozostałe 12 bitów dotyczy uprawnień i bitów setuid / setgid / sticky, tak samo jak dla chmod:
Z historycznych powodów powodem
0100000
jest to, że zwykłe pliki zamiast 0 są takie, że w bardzo wczesnych wersjach Uniksa 0 było dla „małych” plików (nie korzystały one z bloków pośrednich w systemie plików), a wysoki bit flagi trybu był ustawione dla „dużych” plików, które używałyby bloków pośrednich. Pozostałe dwa typy używające tego bitu zostały dodane w późniejszych systemach uniksowych, po zmianie systemu plików.Podsumowując, ogólny układ pola rozszerzonych atrybutów dla Uniksa jest następujący
źródło
040755 << 16L
skonstruowana jest wartość ? W szczególności, jakiej reprezentacji / bazy używa (myślę, że być może Octal ), a co najważniejsze, w jaki sposób język (w tym przypadku interpreter Pythona) wie, co to jest reprezentacja? Hmm, może ten typ jest zadeklarowany w kodzie C. Ponadto z jakiego pliku otrzymujesz wartości „typu pliku”? Pomocne byłoby dodanie niektórych linków / referencji.zipinfo.c
jest to źródło do rozpakowania na Debianie . Alternatywnie można użyć wygodniejszegoapt-get source unzip
. Możesz dołączyć to do swojej odpowiedzi lub użyć niepublicznego źródła. Zazwyczaj cytuję Debiana, ponieważ wierzę, że będą na długo. :-)040755
. Warto wspomnieć o imo dla ludzi, którzy nie wiedzą lub zapomnieli. Oczywiście, to wciąż pozostawia pytanie, skąd wie, że jest to podstawa 8, ale może ten typ jest zadeklarowany jako podstawa 8.stat.h
Plików w systemie Linux (jestem zakładając jest poprawny plik/usr/include/sys/stat.h
) nie zawiera definicji tych stałych w tak jasny sposób, jak plik, który powiązany. Czy są ukryte gdzie indziej? Widzę, że użyłeś tego terminutest macros
, ale nie jestem pewien, co to oznacza.