CRLF مقابل LF أخطاء نهاية السطر التي تؤدي إلى توقف أنظمة التحقق التلقائي

نُشرت في

يُعمل سكربتك في البيئة المحلية، لكنه يفشل في بيئة CI مع خطأ مبهم لـ "مُفسر غير صحيح". السبب غالبًا هو أطراف السطر CRLF. اكتشف ما هي، لماذا تُسبب مشاكل في أنابيب لينكس، وكيف تُعالج المشكلة بشكل دائم باستخدام .gitattributes وإعدادات المحرر.

CRLF مقابل LF: العطل في نهاية السطر الذي يُسبب فشل CI 1
إعلان · حذف؟

أ работت بسكتش الخاص بك بشكل جيد على جهازك المحمول. عندما تُرفع إلى جيثو، يُستقبل من قبل نظام CI، ويُعطل الـ بانل بخطأ مُبهم — شيء من هذا النوع /bin/bash^M: bad interpreter أو مهمة تُغلق بـ 126 دون سبب واضح. السكربت منطقيًا صحيح. لم تُغيّر أي سطر. لكن البناء مُعطل.

في تسع مرات من عشرة، يكون السبب هو توقف السطر. بشكل خاص، توقف السطر المُستخدم في ويندوز (CRLF) المُخفي داخل ملف يُتوقع أن يحتوي فقط على (LF) في أنظمة لينكس. يشرح هذا المقال ما يمثله هذان الرمزان، لماذا يهم الفرق أكثر مما يدركه معظم المطورين، وكيفية إزالة المشكلة بشكل دائم.

ما تعنيه CRLF وLF بالفعل

يحتاج كل ملف نصي إلى طريقة لتحديد نهاية السطر. تستخدم منصات مختلفة على الأنظمة التشغيلية رمزين للتحكم:

  • LF (السطر المُستَمِر، \n، السداسي) 0x0A) — المعيار في يونكس ولينكس. استخدمت ماك أو إس إكس منذ إصدار أو إس إكس. سطر واحد لكل توقف سطر.
  • CRLF (العودة إلى السطر + السطر المُستَمِر، \r\n، السداسي) 0x0D 0x0A) — المعيار في ويندوز، ورثه من دوس، الذي ورثه من أجهزة التلفاز. سطران لكل توقف سطر.

تُستمد أسماء الرموز من الأفعال الفيزيائية القديمة في المطبوعات: عودة السطر كانت تُعيد موضع المطبوعة إلى بداية السطر؛ بينما السطر المُستَمِر كان يُرفع الورق إلى صف جديد. أدخل دوس الرموز بشكل فعلي. اخترع يونكس الطريقة الأقل تعقيدًا واحتفظ فقط بالسطر المُستَمِر.

لماذا يُعطل نظام CI بينما لا يُعطل جهازك المحمول؟

إذا كتبت الكود على ويندوز وحفظ الملف بتنسيق CRLF، فإن كل شيء يعمل محليًا — أدوات ويندوز تتعامل مع كلا التنسيق بسلاسة. لكن نظام CI يُستخدم غالبًا على لينكس، ويعمل مُفسّر الشيل في لينكس على اعتبار \r كأحرف قابلة للطباعة، وليس مسافات. عندما يقرأ بيش (bash) سطرًا في الملف، يرى الأمر كمُرَدّد مع سطر عودة. النتيجة تبدو كالتالي: \r\nفي هذا الخطأ هو طريقة عرض

/bin/bash^M: bad interpreter: No such file or directory

ال ^M من قبل الأجهزة النصية. يحاول بيش تنفيذ سطر تمهيد ينتهي بسطر عودة، وبطبيعة الحال لا يوجد مُفسّر في هذا المسار. \r. يحاول بيش تنفيذ سطر يبدأ بـ "shebang" وينتهي برمز العودة، وبطبيعة الحال لا يوجد مُفسر في هذا المسار.

يظهر نفس المشكلة بطريقة أكثر تدريجية:

  • قيم المتغيرات البيئية التي تنتهي بـ \r تُكسر مقارنات النص بشكل سري.
  • مُخططات دوكر ENTRYPOINT تُفشل في البدء لأن التمهيد مُتضرر.
  • مُخططات بايثون تُقرأ ملفات التكوين وتُحصل على مفاتيح مثل "setting\r" بدلاً من "setting".
  • مُخططات بايثون تُقرأ ملفات التكوين وتُحصل على مفاتيح مثل \r.

مُخططات بايثون تُقرأ ملفات التكوين وتُحصل على مفاتيح مثل

كيفية اكتشاف المشكلة

قبل إصلاح أي شيء، تأكد من أن الملف يحتوي على توقف سطر CRLF. بعض الطرق السريعة:

cat -A deploy.sh

cat -A (لينكس/ماك أو إس) ^M$ السُّطر التي تنتهي بـ CRLF ستُظهر $.

في النهاية. السُّطر التي تنتهي بـ LF فقط تُظهر

file deploy.sh
# deploy.sh: Bash script, ASCII text, with CRLF line terminators

أوامر file

xxd deploy.sh | grep "0d 0a"

أو xxd أو hexdump 0a أي مطابقة تؤكد وجود CRLF. إذا رأيت فقط

كيفية إصلاح المشكلة

dos2unix (الحل الأسرع)

تُثبت مرة واحدة، وتُستخدم على أي ملف:

# Install
sudo apt install dos2unix    # Debian/Ubuntu
brew install dos2unix        # macOS

# Convert a single file
dos2unix deploy.sh

# Convert all shell scripts in the repo
find . -name "*.sh" -exec dos2unix {} \;

sed (بدون أداة إضافية)

sed -i "s/\r//" deploy.sh

tr (مُتوافق مع POSIX)

tr -d "\r" < deploy.sh > deploy_fixed.sh && mv deploy_fixed.sh deploy.sh

كيفية منع المشكلة: إعداد جيت

إصلاح الملفات بعد حدوثها هو حل مُتأخر. الحل المُدائم هو إخبار جيت كيف يجب التعامل مع توقف السطر بحيث لا يصل المشكلة إلى مخزنك.

النهج المُقترح (.gitattributes)

أ .gitattributes يُفرض توقف السطر المتسق على كل مُستخدم، بغض النظر عن إعدادات جيت المحلية. أضف هذا إلى جذع المخزن:

# Normalize all text files to LF in the repo
* text=auto eol=lf

# Explicitly enforce LF for files that must never have CRLF
*.sh text eol=lf
*.bash text eol=lf
Makefile text eol=lf
Dockerfile text eol=lf
*.yaml text eol=lf
*.yml text eol=lf
*.json text eol=lf

# Binary files — do not touch
*.png binary
*.jpg binary
*.gif binary
*.zip binary
*.gz binary

ال text=auto eol=lf السطر يُخبر جيت بتحديد الملفات النصية تلقائيًا وتخزينها بـ LF بغض النظر عن نظام التشغيل الذي يستخدمه المطور. السطور المُحددة أدناه تُثبّت الملفات التي قد تؤدي إلى أخطاء أثناء التشغيل.

بعد إضافة أو تغيير .gitattributes، أعد تطبيق الملفات المُتتبع في المخزن:

git add --renormalize .
git commit -m "normalize line endings"

الإعداد الأساسي لـ autocrlf (مُخصص فقط للجهاز)

يحتوي جيت على إعداد عالمي يُعرف باسم core.autocrlf يُتحكم فيه تغيير توقف السطر أثناء التحقق من الملفات والتعديل. القيم المُوصى بها تعتمد على نظام التشغيل الخاص بك:

# Windows — convert CRLF to LF on commit, LF to CRLF on checkout
git config --global core.autocrlf true

# Linux/macOS — convert CRLF to LF on commit, no conversion on checkout
git config --global core.autocrlf input

المشكلة في الاعتماد على core.autocrlf بحد ذاته: يُطبق فقط على الجهاز الذي تم تعيينه. يمكن أن يُرفع ملفات CRLF من قبل مُستخدم لم يُعدّل الإعداد. الملف يُفرض من قبل المخزن نفسه، وبالتالي يكون أكثر موثوقية. .gitattributes يُفرض ملف file من قبل المخزن نفسه، لذا فهو أكثر موثوقية بشكل صارم.

إعدادات المحرر لضبطها بشكل صحيح

يُعد المحرر أول خط دفاع. بعض الإعدادات السريعة:

فيديو سي ---

يُظهر مُحدد السطر في شريط الحالة (المنطقة السفلى اليمنى). انقر عليه لتبديل بين CRLF وLF. لضبط القيمة الافتراضية لملفات جديدة، أضف هذا إلى ملفك settings.json:

{
  "files.eol": "\n"
}

مُحررات جيت برو (إنتيليج، ويبستورم، بايتشارم)

انتقل إلى إعدادات → محرر → نمط الكود وأعد مُحدد السطر ل يونكس وماك أو إس (\n)يمكنك أيضًا إضافة ملف .editorconfig في جذع المخزن:

[*]
end_of_line = lf
insert_final_newline = true

المحررات الحديثة تُحترم .editorconfig بشكل طبيعي أو من خلال مُلحق. تثبيت هذا الملف في المخزن يعني أن المُستخدمين يحصلون على إعدادات متسقة دون الحاجة إلى تكوين يدوي.

القائمة الكاملة للإرشادات

إذا كنت تُحدّث مخزن يحتوي على مشاكل في توقف السطر، فابدأ بالعمل على هذا التسلسل:

  1. أضف عمودًا إلى جانب العمود القديم .gitattributes ملف مع * text=auto eol=lf وأوامر صريحة لملفات السكربت، وملفات دوكر، وملفات التكوين.
  2. أضف ملف .editorconfig ملف مع end_of_line = lf.
  3. قبل إضافة أي فهرس. تأكد من وجود المشكلة أولاً. git add --renormalize . && git commit -m "normalize line endings" لإصلاح الملفات المُتتبع في المخزن.
  4. قبل إضافة أي فهرس. تأكد من وجود المشكلة أولاً. dos2unix على أي سكربتات غير مُتتبع سيُستخدم على لينكس.
  5. مجموعة core.autocrlf input مُتاحة عالميًا على أجهزة لينكس/ماك أو إس؛ true على ويندوز.
  6. أضف خطًا للتحقق في نظام CI — مثل grep -rUl $'\r' *.sh — للكشف عن أي تراجع قبل أن يصل إلى تطبيق.
هل تريد حذف الإعلانات؟ تخلص من الإعلانات اليوم

تثبيت ملحقاتنا

أضف أدوات IO إلى متصفحك المفضل للوصول الفوري والبحث بشكل أسرع

أضف لـ إضافة كروم أضف لـ امتداد الحافة أضف لـ إضافة فايرفوكس أضف لـ ملحق الأوبرا

وصلت لوحة النتائج!

لوحة النتائج هي طريقة ممتعة لتتبع ألعابك، يتم تخزين جميع البيانات في متصفحك. المزيد من الميزات قريبا!

إعلان · حذف؟
إعلان · حذف؟
إعلان · حذف؟

ركن الأخبار مع أبرز التقنيات

شارك

ساعدنا على الاستمرار في تقديم أدوات مجانية قيمة

اشتري لي قهوة
إعلان · حذف؟