কেন লুপের জন্য "তর্ক খুব দীর্ঘ" ত্রুটি বাড়ায় না?


9

আমি দেখতে পেয়েছি যে এটি "তর্কটি খুব দীর্ঘ" ত্রুটি বাড়িয়ে তুলবে:

ls *.*

এবং এটি এটি উত্থাপন করবে না:

for file in *.*
do
    echo $file
done

কেন?


আপনি উভয় পরীক্ষায় একই শেল ব্যবহার করেছেন? সম্ভবত /bin/bashবনাম /bin/sh(যা সম্ভবত ড্যাশের লিঙ্ক)?
ম্যাক্সলেপজিগ

হ্যাঁ, আমি ফাইলের নাম সহ 10000 ফাইল নিয়ে পরীক্ষাটি করেছি যা বেশ দীর্ঘ। "ls *" ব্যর্থ হয়েছে এবং "for in f" সফল হয়েছে।
lamwaiman1988

উত্তর:


13

"আর্গুমেন্ট খুব দীর্ঘ" ত্রুটিটি হ'ল E2BIG, execveসিস্টেম কল দ্বারা উত্থাপিত যদি আর্গুমেন্টগুলির মোট আকার (প্লাস্টিকের পরিবেশ, কিছু সিস্টেমে) খুব বড় হয়। execveকল এক যে বাহ্যিক প্রসেস শুরু বিশেষভাবে একটি ভিন্ন এক্সিকিউটেবল ফাইল লোড হবে (সেখানে একটি ভিন্ন কল, forkএকটি পৃথক প্রক্রিয়া যার কোড একই এক্সিকিউটেবল ফাইল থেকে এখনও চলমান জন্য)। forতাই এটি কলিং সঙ্গে যুক্ত নয় লুপ, একটি অভ্যন্তরীণ শেল কনস্ট্রাক্ট হয় execve। কমান্ডটি ls *.*ত্রুটি উত্থাপন করে যখন গ্লোব প্রসারিত হয় না তবে কখন lsডাকা হয়।

execveE2BIGকমান্ডের কাছে আর্গুমেন্টগুলির মোট আকার ARG_MAX সীমাটির চেয়ে বড় হলে ত্রুটিটি ব্যর্থ হয় । কমান্ডের সাহায্যে আপনি আপনার সিস্টেমে এই সীমাটির মান দেখতে পাবেন getconf ARG_MAX। (আপনার পর্যাপ্ত স্মৃতি থাকলে আপনি এই সীমাটি অতিক্রম করতে পারবেন; ARG_MAXগ্যারান্টির আওতায় রেখে execveযতক্ষণ কোনও সম্পর্কযুক্ত ত্রুটি না ঘটে ততক্ষণ কাজ করবে।)


এবং কেন শেলের একটি সীমা ছিল না?
lamwaiman1988

1
@ gunbuster363 execveকার্নেল দ্বারা সীমাটি প্রয়োগ করা হয়েছে, এটি সীমাবদ্ধ রাখে কারণ আর্গুমেন্টগুলি এক পর্যায়ে কার্নেল মেমরির মাধ্যমে অনুলিপি করা প্রয়োজন এবং ব্যবহারকারী প্রক্রিয়াগুলি শেল মেমরির একটি নির্বিচার পরিমাণের জন্য অনুরোধ করার অনুমতি দেওয়া যায় না। শেলের ভিতরে, কোনও সীমা থাকার কোনও কারণ নেই, ভার্চুয়াল মেমরির সাথে ফিট করে এমন কোনও কিছুই ঠিক আছে।
গিলস 'অশুভ হওয়া বন্ধ করুন'

5

আমি মনে করি যে প্রথম উদাহরণটিতে একটি / জুড়ি সিস্টেম কলের মাধ্যমে lsকার্যকর করা হয়েছে, দ্বিতীয়টিতে, সমস্ত কাজ অভ্যন্তরীণ ।bashforkexecbash

execকল সীমা আছে, অভ্যন্তরীণ পরিশ্রমী bash(ভালো বা, বিভিন্ন সীমা সঙ্গে কিছুই করার আছে হয়েছে পরিবর্তে নেই exec, সম্ভবত উপলব্ধ মেমরি পরিমাণ)।


তোমার সীমা জানতে পারেন execমধ্যে /usr/include/linux/limits.hসাধারণত হিসাবে সংজ্ঞায়িত করা ARG_MAX
jw013

যদি আমরা লুপের জন্য শেলটি ব্যবহার করি, আপনি কি মনে করেন যে আইটেমের একটি বড় তালিকা সমস্ত র‌্যাম ব্যবহার করবে?
lamwaiman1988

এই উত্তরটি ভুল। এটি 'অভ্যন্তরীণ' নয় এটি কেবল আর্গুমেন্ট এবং আদেশের সীমা আলাদা different
বহুব্যাপী

5

কারণ lsএটির ক্ষেত্রে একটি যুক্তি, এবং যুক্তির সংখ্যা সীমিত।

forচক্রের ক্ষেত্রে এটি কেবল আইটেমের একটি তালিকা। এর জন্য কোনও সীমা নেই (যতদূর আমি সচেতন)।


শেল বিস্তারের জন্য অবশ্যই সীমা রয়েছে। এটি আপনার কতটা র‌্যাম উপলব্ধ রয়েছে তার সাথে এটি অনেকটা সম্পর্কিত this আমার 4 জিবি র‌্যাম সিস্টেমটি একটি for i in {00000001..20000000} ;do ((10#$i==1)) && break; done
গ্যাসকেটটি

4
@ ফ্রেড আমি সত্যিই ভাবিনি যে সীমা হিসাবে র‌্যাম উল্লেখ করা দরকার।
আইমন

2
এটির প্রয়োজন হতে পারে না তবে এটির মতামত প্রকৃতি .. কেউ এটি আকর্ষণীয় বা এমনকি মূল্যবান মনে করতে পারে।
পিটার.ও

@ ফ্রেড: আসলে হ্যাঁ, যদি খুব বড় যুক্তি প্রসারিত করা একটি সাধারণ সমস্যা ছিল, তবে সমস্ত কিছু স্মরণে না রেখে এটিকে বাস্তবায়ন করা সম্ভব হত।
মাত্তিও
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.