نظرة 30 ثانية: شغّلت سكريبت حالة الترجمة، والشاشة كتبت 4546، كلها في
root. على GitHub، تكامل Linux المستمر (CI) كان أخضر. اكتشفت لاحقًا أمرين. الشرطة المائلة العكسية في مسارات Windows، السكريبت يستخدم الشرطة المائلة ليقسم بها فلا ينجح. البايت الثاني لحرف «功» في Big5، هو نفسه\في ASCII. أمران بآليتين مختلفتين، لكنهما كثيرًا ما يظهران معًا على جهاز Windows صيني تقليدي واحد.
أحافظ على سكريبت حالة ترجمة Taiwan.md على Windows 11 بلغة zh-TW. تلك الليلة كالمعتاد شغّلت i18n-status.py، وانتظرت الطرفية لتطبع الأرقام. وحدة التحكم كانت cp950. المخرجات لم تحوي نصًا أحمر.
توقفت الشاشة عند 4546. كلها في تصنيف واحد اسمه root. Technology كان 0.
في نفس الأسبوع دفعت إلى GitHub، وعلى Linux كان CI أخضر.
متغير السكريبت يسمى zh_articles، وهو يمسح ما تحت knowledge باستثناء المجلدات الإنجليزية و about وتلك التي تبدأ بشرطة سفلية، والمسارات اليابانية والكورية والعربية تُحسب أيضًا. تلك الليلة لم يستطع حتى استخراج اسم التصنيف، فأُلقيت أكثر من أربعة آلاف مسار في نفس الخانة. لا استثناءات، لا تحذيرات. الإحصائيات بدت وكأن الموقع بأكمله معطل، مع أن الملفات لم تنقص واحدة.1
المسارات على القرص هي knowledge\Technology\مقالة-ما.md، والمجلدات تفصل بينها شرطة مائلة عكسية. السكريبت يستخدم split('/') لأخذ اسم التصنيف. على Linux هذا السطر يعمل، لأن المسارات أصلًا بالشرطة المائلة. على Windows لا يقطع الشرطة المائلة العكسية، فتعود المسار كاملًا كما هي، وتُرمى المقالة في root الافتراضي.2
بعد تعديل الكود ليدع pathlib يتعامل مع المجلدات، أصبح تحت Technology 59 مقالة، مطابقة لما في المجلد. بينهما افتراض واحد فقط: أي نوع من الخطوط تستخدم آلتك لتفصل المجلدات.
نفس المسار، طريقتا قطع. split('/') لم يجد الشرطة المائلة، فأعاد المسار كاملًا؛ PureWindowsPath تعرف الشرطة المائلة العكسية، فعاد Technology. من إعداد مساهمي Taiwan.md، CC BY-SA 4.0.
📝 ملاحظة القيّم: صياغة السكريبت لم تكن خاطئة، و CI بالفعل أجرى الاختبارات. الشرخ يقع بين «الآلة التي يجلس عليها المؤلف فعليًا» و «الآلة التي يظن الأداة أنك تجلس عليها». هذا الشق لا يتبع لأي مرحلة، لذا لا أحد مسؤول عن مراقبته.
الشرطة المائلة داخل «功»
المسارات طبقة أولى. الطبقة الثانية أقدم بكثير، مدفونة داخل الحرف.
أُقر Big5 عام 1984، الحرف الصيني الواحد بايتان. إذا وقع البايت الثاني بين 0x40 و 0x7E، يتداخل مع رموز ASCII الشائعة: [、]、{、}、\、|. الأستاذ المساعد السابق في قسم إدارة المعلومات بجامعة تشاو يانغ للتكنولوجيا، هونغ تشاو-قوي (تقاعد في أغسطس 2023)، كتب في صفحة تعليمية: «بما أن 40-7E هو نطاق أكواد ASCII للرموز الشائعة، فقد يسبب أحيانًا بعض المتاعب للمبرمجين.»3
رمز «功» هو A5 5C. ذلك 0x5C الأخير، في ASCII هو الشرطة المائلة العكسية \. برنامج يمسح سلسلة بايتًا بايتًا ويعامل \ كحرف هروب أو فاصل، عند مسحه للبايت الثاني من «功»، يظن أنه واجه مسارًا. إن كان اسم الملف يحوي «功»، أو المسار يحوي «功»، فهما قد يتعثران هنا.
مطورو تايوان وهونغ كونغ يسمونه «許功蓋»: «許» هو B3 5C، «功» هو A5 5C، «蓋» هو BB 5C، ثلاثة حروف شائعة مكتوبة متتالية تشبه اسم شخص.4 هونغ تشاو-قوي أورد أيضًا «加也程陣功»، بايتاتها الثانية تصطدم على التوالي بـ [、]、{、}、\، وصنع أداة مسح اسمها b5tm.3 عندما يُعطى عطل اسم شخص، فغالبًا لأنه يظهر بتردد كافٍ، فيضطر جيل كامل لإيجاد طريقة للإشارة إليه بالكلام.
عام 2015، مؤلف مدونة «الخيط المظلم» انتقل إلى Visual Studio 2015. ملفات .cs القديمة لا تزال محفوظة بـ BIG5. بعد أن أصبح المترجم يستخدم Roslyn، حروف «許功蓋» داخل الملفات صارت أخطاء ترجمة.
بعد يومين زميل قال له، هم أيضًا انتقلوا وتعثروا طويلًا، وأخيرًا زحفوا عبر المقالات حتى وصلوا مقالته. مستخدم شبكة لديه آلاف الملفات، حوّل واحدًا وبقي فيه الكثير، «فلم يجد بدًا من قول Goodbye لـ VS2015». لاحقًا كتب أداة صغيرة لتحويل دفعي إلى UTF-8، لأن الحفظ اليدوي لا ينتهي.5
هذا ليس نفس أمر split('/') السابق. واحد أداة حديثة تفترض كيف يبدو المسار. واحد قرار قبل أربعين عامًا باعتماد بايتين، فسكن رمز داخل جسد الحرف. آليتان مختلفتان، لكن الفاتورتين كثيرًا ما تصلان معًا على نفس آلة cp950. جانب الإدخال كيف يُدخل الحرف إلى الحاسوب، انظر 東亞文字輸入法. هنا نتحدث عما بعد وجود الحرف على القرص، هل سلسلة الأدوات لا تزال تعرفه.
القيم الافتراضية لم تفتح فرعًا لهذه الآلة
Git يفعّل core.quotePath افتراضيًا. أسماء الملفات التي بايتاتها أكبر من 0x80، git status يطبعها بصيغة \344\270\255 ثمانيية. أسماء الملفات الصينية لا تزال هناك، أنت فقط كل يوم لا تفهم ما يقوله مستودعك.6 هو يهرب بايتات UTF-8 العليا. 0x5C في Big5 خط آخر. كلاهما يبدو شرطة مائلة عكسية، لكن السببين مختلفان.
نفس الملف، تحت القيمة الافتراضية سلسلة \345\212\237. الشرطة المائلة العكسية هنا هي هروب أضافه Git، لا علاقة لها بـ 0x5C داخل «功». من إعداد مساهمي Taiwan.md، CC BY-SA 4.0.
Python 3 على Windows إن استُخدم open() دون encoding='utf-8'، قد يستخدم لغة النظام افتراضيًا. نفس ملف UTF-8، Linux يقرأه بنجاح، هذه الآلة تستخدم cp950 لتفسره، فالترقيم أو الرموز الصوتية تتلف.7 دفعت الثمن مرة: استخدمت Get-Content | Set-Content في PowerShell 5.1 لتحويل ملف UTF-8، الشرطة الطويلة في diff تحولت إلى ??. تلك أيضًا ضريبة افتراضية، وليست الموضوع الثاني.
عند حمل رسائل الحالة لـ emoji، وحدة التحكم cp950 هذه تنهار مباشرة. مجموعة الحروف لا تحوي تلك الرموز، Python لا يستطيع طباعتها، الاستثناء ينفجر للطبقات العليا. CI على Linux لا يكشف هذا، لأنه لا يعمل على هذه الآلة.
Git، Python، مسارات الأمثلة في CI فيها $HOME/project/src، لم تفتح فرعًا لـ zh-TW Windows.
هونغ تشاو-قوي في مقابلة مع iThome عام 2015، تحدث عن صيغة فتح ملفات الحكومة، وكم ستبقى حية. التقرير نقل معناه: إذا استخدمت الحكومة منتجات مايكروسوفت فقط لفتح ملفات البيانات، فمعنى ذلك الإيمان بأن عمر مايكروسوفت سيطول أكثر من جمهورية الصين (تايوان).8 تلك الجملة تتحدث عن صيغ الملفات وسنوات الحفظ. البيانات مربوطة بأي مجموعة أدوات افتراضية، متى طال الزمن، تصبح مسألة من لا يزال يستطيع القراءة. التعاون مفتوح المصدر مربوط ببيئة افتراضية لنوع معين من الآلات. شد الحبل بين التكنولوجيا المدنية وصيغ ملفات الحكومة، انظر 開源社群與g0v. ثقافة المطورين التايوانيين في امتصاص هذا الفارق طويلًا، انظر 台灣開源精神.
فاصل المسار، ترميز الطرفية، $HOME في أمثلة CI، لا يوجد فرع مفتوح لهذه الآلة. يوم أُسيء تصنيف 4546 مسارًا، لم يُبلّغ أي سطر كود عن خطأ. الإحصائيات بدت طبيعية، حتى تجلس أمام هذه الآلة.
قراءة موسعة
- 台灣開源精神: ثقافة وسياق مشاركة المطورين التايوانيين في المصدر المفتوح.
- 東亞文字輸入法: كيف تُدق الحروف إلى الحاسوب، من جداول الرموز إلى لوحة المفاتيح.
- 開源社群與g0v: التعاون بين البيانات المفتوحة وصيغ الحكومة.
مصادر الصور
- رمز «功» في Big5 والشرطة المائلة العكسية (الرئيسية): رسم توضيحي من إعداد مساهمي Taiwan.md، CC BY-SA 4.0، مخزن في
public/article-images/technology/big5-gong-5c-backslash.webp. السطر بالأسفل هو مخرجات تنفيذ Python 3 الفعلي لـ'許功蓋'.encode('big5')، مواضع الرموز مطابقة لمقالة Big5 في ويكيبيديا.4 - split('/') مقابل PureWindowsPath: من إعداد مساهمي Taiwan.md، CC BY-SA 4.0، مخزن في
public/article-images/technology/windows-path-split-vs-pathlib.svg. المحتوى نتائج تنفيذ Python 3 الفعلية؛PureWindowsPathعلى أي نظام تشغيل يقطع المسارات بقواعد Windows، لذا لا حاجة لآلة Windows لإعادة الإنتاج. - مخرجات Git core.quotePath الثمانيية: من إعداد مساهمي Taiwan.md، CC BY-SA 4.0، مخزن في
public/article-images/technology/git-quotepath-octal-cjk.svg. المحتوى مخرجاتgit status --shortالفعلية بعد إضافة اسم ملف هذه المقالة إلى مستودع مؤقت؛ هذا السلوك لا علاقة له بنظام التشغيل.
المراجع
- taiwan-md PR #1260 — دمج 2026-07-26. قبل الإصلاح Windows categories فقط root: 4546، بعد الإصلاح Technology zh: 59. أُزيل أيضًا emoji كانت تسبب انهيار وحدة تحكم cp950.↩
- Microsoft Learn: تنسيقات مسارات الملفات على أنظمة Windows — توثيق .NET يوضح أن مسارات DOS التقليدية تستخدم الشرطة المائلة العكسية كفاصل للمجلدات، والشرطة المائلة تُحوّل إلى عكسية.↩
- هونغ تشاو-قوي: مشاكل كود Big-5 التي قد تواجهها عند البرمجة — صفحة تعليمية تسرد الحروف الشائعة التي بايتها الثاني يقع في منطقة خطر ASCII (加也程陣功)، وتقدم أداة المسح b5tm. ذيل الصفحة لم يذكر الرتبة الوظيفية. iThome عام 2015 وصفه بأستاذ مساعد. صفحته الشخصية تحوي 1997 إلى 2023 في إدارة معلومات تشاو يانغ، تقاعد أغسطس 2023.↩2
- ويكيبيديا: Big5 — يوضح «功» 0xA55C، «許» 0xB35C، «蓋» 0xBB5C، ويذكر أن هذه المشكلة تُدعى بالهزل «許功蓋».↩2
- الخيط المظلم: آلة الحفر — حل مشكلة توافق ملفات برنامج BIG5 مع VS2015 — سجل 2015 عن أخطاء ترجمة Visual Studio 2015 عند ترجمة كود مصدر BIG5 بسبب «許功蓋». النص يحوي «فلم يجد بدًا من قول Goodbye لـ VS2015».↩
- git-config: core.quotePath — التوثيق الرسمي يوضح أن القيمة الافتراضية تعرض المسارات التي بايتاتها أكبر من 0x80 كسلاسل هروب ثمانيية.↩
- Python 3: open() — توثيق الدالة يشير إلى أنه عند عدم تحديد encoding، قد يستخدم لغة النظام افتراضيًا كترميز.↩
- iThome: مقابلة هونغ تشاو-قوي — مقابلة 2015، النص يصفه بأستاذ مساعد قسم إدارة المعلومات بجامعة تشاو يانغ للتكنولوجيا. الصفحة الأصلية كثيرًا ما تعيد 403، جملة عمر مايكروسوفت مستخدمة فقط من نقل التقرير الظاهر في نتائج البحث، لا تُعتبر نقلًا حرفيًا أصليًا.↩