Jag har försökt att få synkroniseringsprogrammet
unison att fungera i mac os x.
Min server använder utf-8 som teckenkodning på filsystemet. Vad mac använder verkar vara normaliserad utf-8 (se
här för intressant läsning).
Unison funkar inte alls särskilt bra för mig på sökvägar som innehåller icke-ascii-tecken. En katalog som heter "företag" dupliceras till originalet och en kopia som renderas likadant med en annorlunda representation. Dvs filnamnet är binärt olika men bokstäverna är samma. Det är just detta som unicode-normalisering strävar efter att lösa.
Först trodde jag att det är unison som är
boven i dramat, men det är snarare Apples fel! Citerat ur manualsidan för convmv:
Filesystem issues
Almost all POSIX filesystems do not care about how filenames are encoded, here are some exceptions:
HFS+ on OS X / Darwin
Linux and (most?) other Unix-like operating systems use the so called normalization form C (NFC) for its UTF-8 encoding by default
but do not enforce this. Darwin, the base of the Macintosh OS enforces normalization form D (NFD), where a few characters are
encoded in a different way. On OS X it’s not possible to create NFC UTF-8 filenames because this is prevented at filesystem layer.
On HFS+ filenames are internally stored in UTF-16 and when converted back to UTF-8, for the underlying BSD system to be handable,
NFD is created. See http://developer.apple.com/qa/qa2001/qa1173.html for defails. I think it was a very bad idea and breaks many
things under OS X which expect a normal POSIX conforming system. Anywhere else convmv is able to convert files from NFC to NFD or
vice versa which makes interoperability with such systems a lot easier.
Nog med inledning, detta fick mig att läsa på lite om unicode.
Jag använder mitt katalognamn "företag" som exempel.
Det kodas i utf-8 som
66 c3 b6 72 65 74 61 67
ö-et blir alltså hex c3-b6 eller binärt
11000011
10110110 där jag markerat utf-8-prefixen med fetstil. Payload är alltså 11 konkatenerat med 110110 villket är F6 hex som är
"direktformen" för ö, eller "Latin Small Letter O with diaeresis" som det heter. Låter snarare som en sjukdom....
Om jag nu kollar vad som hänt på servern ser jag att det finns två mappar som heter företag.
$ls |grep retag
företag
företag
en undersökning av representationen (genom att pipa till hexdump -C) ger (jag har tagit bort newline 0a manuellt):
66 6f cc 88 72 65 74 61 67
66 c3 b6 72 65 74 61 67
ö-et kodas alltså som 6f cc 88 i det första fallet och c3 b6 i det andra (som jag förväntat mig.)
En avkodning enligt ovan ger att 6f är bokstaven o, och prickarna kommer till i efterhand genom cc 88 som binärt är
11001100
10001000 och lasten därmed 0x308 som
betyder två prickar(leta efter rad med 0300 i vänstra kolumnen och kolumn med huvud "8").
Det som behövs för att unison ska förstå att dessa två filnamn egentligen är samma är
normalisering.
Det är verkligen inte trivialt att hantera teckenkodning korrekt!