Stává se to proto, že některé nástroje Windows zjevně používají zpětná lomítka (\
) jako oddělovače tam, kde by měly používat lomítka (/
). Zpětné lomítko v Unixu může být součástí názvu souboru nebo adresáře.
Specifikace formátu souboru .ZIP (verze:6.3.5, když to píšu, revidovaná 20. listopadu 2018) uvádí:
4.4.17.1 Název souboru s volitelnou relativní cestou. Uložená cesta NESMÍ obsahovat písmeno jednotky nebo zařízení nebo úvodní lomítko. Všechna lomítka MUSÍ být lomítka
/
na rozdíl od zpětných lomítek\
kvůli kompatibilitě se souborovými systémy Amiga a UNIX atd. Pokud vstup pochází ze standardního vstupu, není zde žádné pole pro název souboru.
Tento soubor je zmíněn společností Microsoft v dokumentu Mitigation:ZipArchiveEntry.FullName
Oddělovač cesty:
Počínaje aplikacemi, které cílí na rozhraní .NET Framework 4.6.1, oddělovač cest použitý v
ZipArchiveEntry.FullName
vlastnost se změnila ze zpětného lomítka (\
) používané v předchozích verzích rozhraní .NET Framework na lomítko (/
). [...]Dopad
Tato změna uvádí implementaci .NET do souladu s oddílem 4.4.17.1 specifikace formátu souboru .ZIP a umožňuje dekomprimovat archivy .ZIP na systémech jiných než Windows.
Dekomprimace souboru zip vytvořeného aplikací, která cílí na předchozí verzi rozhraní .NET Framework na operačních systémech jiných než Windows, jako je Macintosh, nezachová adresářovou strukturu. Například na Macintoshi vytvoří sadu souborů, jejichž název zřetězí cestu k adresáři spolu s libovolným zpětným lomítkem (
\
) znaky a název souboru. V důsledku toho není zachována adresářová struktura dekomprimovaných souborů.
Všimněte si, že problém může existovat, pokud archivátor používal nějakou starou verzi .NET Framework nebo pokud ji nepoužíval vůbec, ale implementoval svůj vlastní (nezávislý) přístup k souborům zip.
Jeden může zaznamenat stejný problém s rar:Unrar vytváří soubory se zpětnými lomítky v názvech namísto řádné hierarchie adresářů.
Tato otázka na Unix &Linux SE může být užitečná:Převeďte ZIP vytvořený Windows na Linux (problém s interními cestami). Můj (poněkud experimentální) přístup je v této odpovědi.
Toto je ve skutečnosti chyba v Microsoft.PowerShell.Archive
:
https://github.com/PowerShell/Microsoft.PowerShell.Archive/issues/48
...což bude vyřešeno v tomto PR, navrženém pro verzi 1.2.3:
https://github.com/PowerShell/Microsoft.PowerShell.Archive/pull/62
Mezitím je to rychlá oprava (kredit):
for file in *\\*; do target="${file//\\//}"; mkdir -p "${target%/*}"; mv -v "$file" "$target"; done