linux - هل تنطبق قيود "قائمة الوسيطات طويلة جدًا" على أساسيات shell؟
bash unix (2)
لقد قمت باستعراض العديد من المنشورات على Stack Overflow بالإضافة إلى عدد قليل من المجتمعات ذات الصلة فيما يتعلق
argument list too long
موضوع
argument list too long
ولا يبدو لي أنه من الواضح أن ما إذا كان تقييد الطول ينطبق على أساسيات shell أم لا.
لنفترض أنني أريد تمرير سلسلة طويلة جدًا إلى أمر عبر الإدخال القياسي:
string="a very long list of words ..."
هل يمكن ان اقول:
# not using double quotes around $string is deliberate
printf '%s\n' $string | cmd ...
أو
cmd <<< $string
أو حتى
xargs
إلى
xargs
:
printf '%s\n' $string | xargs cmd ...
هل يمكن لشخص توضيح ذلك؟
لا يبدو لي أن أعرف ما إذا كان تقييد الطول ينطبق على الأجزاء الأساسية للأصداف أم لا.
ربما لا ، ولكن يجب عليك التحقق من الكود المصدري لإصدار معين من
bash
(لأنه برنامج مجاني).
ومع ذلك ، من الواضح أن هناك بعض القيود الأكبر (بشكل خاص لأن بعض
malloc
يتم إجراؤها داخل
bash
قد تفشل) ، ولكن بعد ذلك ستظهر لك رسالة خطأ أو سلوك آخر.
AFAIK ، يتم إعطاء خطأ في قائمة الوسيطة بسبب
execve(2)
بالفشل مع
E2BIG
، والوظائف المضمنة من bash لا
execve
ثم
execve
(مثل أوامر استدعاء البرامج الخارجية تفعل).
في الممارسة العملية ، قد تظهر
E2BIG
مع بضع مئات الآلاف من بايت (يعتمد الحد الدقيق على kernel والنظام) ولكن أعتقد أنه يمكن استخدام الأجزاء المضمنة على عدة عشرات من الميجابايت (على سطح المكتب اليوم).
لكن YMMV (حيث يمكنك استخدام
setrlimit(2)
تقوم ببعض
setrlimit(2)
...).
لن أوصي بمعالجة غيغا بايت من البيانات من خلال البنية المدمجة.
راجع للشغل ،
xargs(1)
يمكن أن تكون مفيدة ، ويمكنك حتى رفع الحد (ل
E2BIG
) عن طريق إعادة ترجمة النواة الخاصة بك (وكذلك من خلال بعض الطرق الأخرى ، في النواة الحديثة).
قبل بضع سنوات كان ذلك بمثابة دافع قوي لي لإعادة ترجمة النواة.
في bash ، لا يتم تطبيق القيد الذي يفرضه نظام التشغيل على طول سطر الأوامر والذي يتسبب في
argument list too long
الخطأ
argument list too long
على أساسيات shell.
يتم تشغيل هذا الخطأ عندما تقوم
execve()
بإرجاع رمز الخطأ
E2BIG
.
لا يوجد
execve()
معني عند استدعاء مدمج ، لذلك لا يمكن أن يحدث الخطأ.
وبالتالي ، كلتا العمليتين المقترحتين
cmd <<< "$string"
:
cmd <<< "$string"
يكتب
$string
إلى ملف مؤقت ، والذي لا يتطلب تمريره كعنصر argv (أو متغير بيئة ، والذي يتم تخزينه في نفس مجموعة من المساحة المحجوزة) ؛
و
printf '%s\n' "$cmd"
يحدث داخليًا في الغلاف ما لم يتم تعديل تكوين shell ، كما هو الحال مع
enable -n printf
، لاستخدام تطبيق
printf
خارجي.