"আর্গুমেন্টের তালিকা খুব দীর্ঘ": আমার আদেশ না বদলে আমি কীভাবে এটি মোকাবেলা করব?


18

আমি যখন একটি কমান্ড চালিত ls */*/*/*/*.jpgকরি তখন ত্রুটি পাই

-bash: /bin/ls: Argument list too long

আমি জানি কেন এটি হয়: এটি হ'ল কারণ একটি আদেশে আর্গুমেন্টের জন্য জায়গার পরিমাণের উপর কার্নেল সীমা রয়েছে। স্ট্যান্ডার্ড পরামর্শটি হ'ল আমি যে কমান্ডটি ব্যবহার করি তা পরিবর্তন করা, আর্গুমেন্টের জন্য এত জায়গার প্রয়োজন এড়াতে (যেমন, ব্যবহার findএবং xargs))

আমি যদি কমান্ডটি পরিবর্তন করতে না চাই? আমি যদি একই কমান্ডটি ব্যবহার করে যেতে চাই? এই ত্রুটি না পেয়ে আমি কীভাবে জিনিসগুলিকে "কেবলমাত্র কাজ" করতে পারি? কি সমাধান পাওয়া যায়?


দরকারী পড়া: বাশ FAQ 95 । আপনার কমান্ডটি পরিবর্তন না করে আপনার যুক্তি তালিকার সর্বাধিক আকার বাড়াতে বা আপনার ডিরেক্টরি কাঠামোটি পরিবর্তন করতে যাতে কম ফাইল থাকে সেজন্য আপনি পুনরায় সংশোধন করার পাশাপাশি আরও কিছু করতে পারেন না।
jw013

1
@ jw013 লিনাক্স কার্নেল সংস্করণের উপর ভিত্তি করে যুক্তি তালিকাটি বাড়ানো সম্ভব হতে পারে - সাম্প্রতিক সিস্টেমগুলির পরিবর্তন সম্পর্কে বিশদ জানতে unix.stackexchange.com/a/45161/8979 দেখুন ।
উলিচ ড্যাঞ্জেল

@ অরিখডাঙ্গেল, হ্যাঁ, এটি সম্ভব! আমার উত্তর দেখুন; আমার উত্তরটি দেখায় যে এটি কীভাবে করা যায় (লিনাক্সে, সাম্প্রতিক পর্যায়ে যথেষ্ট কার্নেল সহ)।
ডিডব্লিউ

উত্তর:


26

লিনাক্সে, কমান্ড আর্গুমেন্টগুলির জন্য সর্বাধিক পরিমাণের পরিমাণ উপলব্ধ স্ট্যাক স্পেসের পরিমাণের 1/4 তম। সুতরাং, একটি সমাধান হ'ল স্ট্যাকের জন্য উপলব্ধ জায়গার পরিমাণ বৃদ্ধি করা।

সংক্ষিপ্ত সংস্করণ: কিছু চালান

ulimit -s 65536

দীর্ঘতর সংস্করণ: স্ট্যাকের জন্য উপলব্ধ স্থানের ডিফল্ট পরিমাণ 8192 কেবি এর মতো। আপনি উপলব্ধ জায়গার পরিমাণটি দেখতে পারেন:

$ ulimit -s
8192

একটি বৃহত সংখ্যা চয়ন করুন এবং স্ট্যাকের জন্য উপলব্ধ জায়গার পরিমাণ নির্ধারণ করুন। উদাহরণস্বরূপ, আপনি যদি স্ট্যাকটির জন্য 65536 কেবি পর্যন্ত অনুমতি দেওয়ার চেষ্টা করতে চান তবে এটি চালান:

$ ulimit -s 65536

ট্রায়াল-অ্যান্ড-ত্রুটি ব্যবহার করে আপনার এটি কত বড় হওয়া দরকার তা নিয়ে আপনার চারপাশে খেলতে হবে। অনেক ক্ষেত্রে, এই একটি দ্রুত-এবং-মলিন সমাধান বাক্য গঠন প্রণালী আউট কমান্ড এবং কাজের সংশোধন করার প্রয়োজনীয়তা দূর হবে find, xargsইত্যাদি (যদিও আমি বুঝতে পারছি সেখানে এমনটি অন্যান্য সুবিধা হয়)।

আমি বিশ্বাস করি যে এটি লিনাক্স-নির্দিষ্ট। আমার সন্দেহ হয় এটি সম্ভবত অন্য কোনও ইউনিক্স অপারেটিং সিস্টেমে সহায়তা করবে না (পরীক্ষিত নয়)।


1
আপনি এটির মতো যাচাই করতে পারেন: $ getconf ARG_MAX 2097152 $ ulimit -s 65535 $ getconf ARG_MAX 16776960
অ্যালেক্স

2

এই লিনাক্স জার্নাল নিবন্ধটি 4 টি সমাধান দেয়। কেবলমাত্র চতুর্থ সমাধানে কমান্ড পরিবর্তন করা জড়িত না:

কমান্ড-লাইন আর্গুমেন্টের জন্য কার্নেলের মধ্যে বরাদ্দকৃত পৃষ্ঠাগুলির সংখ্যাটি ম্যানুয়ালি # 4 জড়িত। আপনি যদি অন্তর্ভুক্ত / লিনাক্স / বিনফমটস ফাইলটি লক্ষ্য করেন তবে নীচেরটিকে নীচের দিকে দেখতে পাবেন:

/*
 * MAX_ARG_PAGES defines the number of pages allocated for   arguments
 * and envelope for the new program. 32 should suffice, this gives
 * a maximum env+arg of 128kB w/4KB pages!
 */
#define MAX_ARG_PAGES 32

কমান্ড-লাইন আর্গুমেন্টকে উত্সর্গীকৃত মেমরির পরিমাণ বাড়ানোর জন্য আপনাকে কেবলমাত্র উচ্চতর সংখ্যার সাথে MAX_ARG_PAGES মান সরবরাহ করতে হবে। একবার এই সম্পাদনাটি সংরক্ষণ করা হয়ে গেলে নতুন কার্নেলটিতে কেবল পুনরায় কম্পাইল করুন, ইনস্টল করুন এবং পুনরায় বুট করুন যা আপনি সাধারণত করবেন।

আমার নিজের পরীক্ষার সিস্টেমে আমি এই মানটি 64 এ উন্নীত করে আমার সমস্ত সমস্যা সমাধান করতে সক্ষম হয়েছি extensive ব্যাপক পরীক্ষার পরে, স্যুইচ করার পর থেকে আমি কোনও একটিও সমস্যা অনুভব করিনি। এটি সম্পূর্ণরূপে প্রত্যাশিত যেহেতু MAX_ARG_PAGESto৪-এ সেট করা সত্ত্বেও , আমি যে দীর্ঘতম সম্ভাব্য কমান্ড লাইন তৈরি করতে পারি তা কেবল 256KB সিস্টেম মেমরির দখল করতে পারে - আজকের সিস্টেম হার্ডওয়্যার মানদণ্ডের দ্বারা খুব বেশি নয়।

পদ্ধতি # 4 এর সুবিধাগুলি স্পষ্ট। আপনি এখন সাধারণভাবে যেমন কমান্ডটি চালাতে সক্ষম হন, এবং এটি সফলভাবে সমাপ্ত হয়। অসুবিধাগুলিও সমানভাবে পরিষ্কার। আপনি যদি কমান্ড লাইনে উপলভ্য মেমরির উপলব্ধ সিস্টেম মেমরির পরিমাণ ছাড়িয়ে যান তবে আপনি নিজের সিস্টেমে একটি ডস আক্রমণ তৈরি করতে পারেন এবং এটিকে ক্রাশ করতে পারেন। বিশেষত মাল্টিউজার সিস্টেমগুলিতে, এমনকি একটি সামান্য বৃদ্ধিও উল্লেখযোগ্য প্রভাব ফেলতে পারে কারণ প্রতিটি ব্যবহারকারীকে অতিরিক্ত মেমরি বরাদ্দ করা হয়। অতএব সর্বদা আপনার নিজের পরিবেশে বৃহত্তর পরীক্ষা করুন, কারণ পদ্ধতিটি 4 আপনার জন্য একটি কার্যকর বিকল্প কিনা তা নির্ধারণ করার এটি সবচেয়ে নিরাপদ উপায়।

আমি সম্মত হই যে সীমাবদ্ধতা গুরুতরভাবে বিরক্তিকর।


1

পরিবর্তে ls */*/*/*/*.jpg, চেষ্টা করুন:

echo */*/*/*/*.jpg | xargs ls

xargs(১) জানে, সিস্টেমে সর্বোচ্চ সংখ্যক আর্গুমেন্ট কী আছে এবং নির্দিষ্ট কমান্ড-লাইনকে একাধিকবার কল করার জন্য তার সীমাবদ্ধতার চেয়ে বেশি যুক্তি ছাড়াই কল করার জন্য এটির স্ট্যান্ডার্ড ইনপুটটি ভেঙে দেবে (যাইহোক আপনি এটির চেয়েও কম সেট করতে পারেন) -nঅপশনটি ব্যবহার করে ওএস 'সর্বাধিক )।

উদাহরণস্বরূপ, ধরুন, সীমাটি 3 টি আর্গুমেন্ট এবং আপনার পাঁচটি ফাইল রয়েছে। যে ক্ষেত্রে xargsচালানো হবে lsদুইবার:

  1. ls 1.jpg 2.jpg 3.jpg
  2. ls 4.jpg 5.jpg

প্রায়শই এটি পুরোপুরি উপযুক্ত, তবে সর্বদা নয় - উদাহরণস্বরূপ, আপনি ls(1) আপনার জন্য সমস্ত এন্ট্রি সঠিকভাবে বাছাইয়ের উপর নির্ভর করতে পারবেন না , কারণ প্রতিটি পৃথক- lsদাওয়াত কেবলমাত্র তার দ্বারা প্রদত্ত এন্ট্রিগুলির উপসেটটি সাজিয়ে রাখবে xargs

যদিও আপনি অন্যদের পরামর্শ অনুসারে সীমাটি কাটাতে পারেন, তবুও একটি সীমা থাকবে - এবং কোনও দিন আপনার জেপিজি-সংগ্রহ এটি আবার ছাড়িয়ে যাবে। অসীম সংখ্যার সাথে মোকাবিলা করার জন্য আপনার স্ক্রিপ্ট (গুলি) প্রস্তুত করা উচিত ...


ধারণার জন্য ধন্যবাদ! এটি কোনও খারাপ কাজ নয়। দুটি সতর্কতা: ১. এটি ডিরেক্টরি এবং ফাইলের নামে বিরতি দেয় যার নামে ফাঁকা স্থান রয়েছে, সুতরাং এটি একটি নিখুঁত বিকল্প নয়। ২. এটি কি একই সমস্যাটির সাথে চালিত হতে চলেছে Argument list too longতবে এর echoপরিবর্তে lsশেলগুলিতে যেখানে echoশেল বিল্ট-ইন কমান্ড নেই? (বেশিরভাগ শেলের মধ্যে এটি কোনও সমস্যা নয়, সম্ভবত এটি অপ্রাসঙ্গিক))
ডিডাব্লু

1
হ্যাঁ, ফাইলের নামগুলিতে বিশেষ অক্ষরগুলি একটি সমস্যা। আপনার সেরা বাজিটি হ'ল প্রিডিকেট findদিয়ে ব্যবহার করা -print0- এবং এর আউটপুটটি বিকল্প xargsসহ পাইপ করা -0echoএটি একটি অন্তর্নির্মিত শেল এবং exec(3) এর কমান্ড-লাইন সীমাবদ্ধতায় ভোগে না ।
মিখাইল টি।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.