বিপুল সংখ্যক ফাইল অনুলিপি করতে গিয়ে 'তর্ক তালিকায় খুব দীর্ঘ' ত্রুটি


12

আমি নিম্নলিখিত কমান্ডটি ব্যবহার করছি:

\cp -uf /home/ftpuser1/public_html/ftparea/*.jpg /home/ftpuser2/public_html/ftparea/

এবং আমি ত্রুটি পাচ্ছি:

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

আমি চেষ্টাও করেছি:

ls /home/ftpuser1/public_html/ftparea/*.jpg | xargs -I {} cp -uf {} /home/ftpuser2/public_html/ftparea/

তবুও পেয়েছেন -বাশ: / বিন / এলএস: তর্ক তালিকা খুব দীর্ঘ

কোন ধারনা?


আমি 1 টি ডিরেক্টরি থেকে সমস্ত jpgs অনুলিপি করার চেষ্টা করছি তবে কেবল নতুন ফাইল এবং আপডেট করা হয়েছে।
আইসেলিজার্ড

lsএই ধরণের জিনিস করার জন্য ডিজাইন করা হয়নি। ব্যবহার find
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

সমস্যাটি এলএসের সাথে নয়, শেলটি এলএসে যে পরিমাণ আর্গুমেন্ট চলেছে তা এটি। আপনি ভিআই বা অন্য কোনও অন্তর্নির্মিত কমান্ডের মাধ্যমে একই ত্রুটি পেয়ে যাবেন।
ক্রিস

কিন্তু lsহয় , বিশেষ করে এই কাজ করতে ডিজাইন করা: mywiki.wooledge.org/ParsingLs
পরবর্তী ঘোষণা না হওয়া পর্যন্ত বিরাম দেওয়া।

সত্য, তবে এক্ষেত্রে ত্রুটিটি ls এর সাথে পার্সিং ত্রুটির কারণে নয়, এটি একটি নতুন প্রক্রিয়াতে এক বিলিয়ন আর্গুমেন্ট পাস করার সাথে রয়েছে যা এলএস হতে পারে। এলএস এর অনুপযুক্ত ব্যবহার ছাড়াও, এটি ইউনিক্সের কোনও সংস্থান / নকশার সীমাবদ্ধতার বিরুদ্ধে ঘাঁটিঘাতেও ঘটে। এই ক্ষেত্রে, রোগীর পেটের ব্যথা এবং একটি ভাঙা পা উভয়ই রয়েছে।
ক্রিস

উত্তর:


19

* .jpg শেলটি পরিচালনা করতে পারে তার চেয়ে বেশি তালিকায় প্রসারিত হয়। পরিবর্তে এটি চেষ্টা করুন

find  /home/ftpuser/public_html/ftparea/ -name "*.jpg" -exec cp -uf "{}" /your/destination \;

আমি / home / ftpuser1 / public_html / ftparea / -name "* jpg" -exec cp -uf "{}" / home / ftpuser2 / public_html / ftparea / খুঁজে পেয়েছি এবং নিম্নলিখিত ত্রুটিটি পেয়েছি: ex -exec '
আইসেলিজার্ড

আপনি সিপির শেষ যুক্তিটি মিস করছেন, উত্তরদাতা আপনাকে সঠিক বলেছে। আপনার বাস্তবায়ন ডাবল পরীক্ষা করুন। মনে রাখবেন যে এই উত্তরে "* .jpg" এ থাকা বিন্দুটি অনুপস্থিত রয়েছে, এর ফলে দুর্ব্যবহার হতে পারে (উদাহরণস্বরূপ "মাইজপিজি" নামে সিপি ডির)। নোট করুন তবে তা অদ্ভুত হতে পারে তবে আপনি টাইপ ফাইলটি ব্যবহার করে যা কপি করতে চলেছেন তা ঘনিষ্ঠভাবে নির্দিষ্ট করে তুলতে নিরাপদ করুন (
ডায়ার, সিমলিংকগুলি

কাছাকাছি পরিদর্শন করার পরে আমি "\" মিস করেছি কমান্ডটি শেষ করতে যে-এক্সেকটি সম্পাদন করা উচিত। বোকা আমাকে!
আইসেলিজার্ড

@ অ্যালবার্ট: অনুপস্থিত বিন্দুটি আবারও মাথার জন্য ধন্যবাদ। এটি একটি টাইপ ছিল। উত্তর আপডেট হয়েছে।
শন চিন

এটি এমন নয় যে সিপি এটি পরিচালনা করতে পারে না। শেল পারে না।
d -_- বি

6

সিস্টেম কমান্ডের জন্য আর্গুমেন্টের তালিকা কত দীর্ঘ হতে পারে তার সর্বাধিক সীমা রয়েছে - MAX_ARG_PAGESকার্নেলটি সংকলন করা হয় তার মানের উপর ভিত্তি করে এই সীমাটি বিকৃত-নির্দিষ্ট হয় এবং কার্নেলটি পুনরায় সংশোধন না করে পরিবর্তন করা যায় না।

শেল দ্বারা যেভাবে গ্লোব্বিং পরিচালনা করা হয় তার কারণে আপনি একই আর্গুমেন্ট ("* .jpg") ব্যবহার করলে এটি বেশিরভাগ সিস্টেম কমান্ডকে প্রভাবিত করে। যেহেতু গ্লোবটি প্রথমে শেল দ্বারা প্রক্রিয়া করা হয় এবং তারপরে কমান্ডটি পাঠানো হয়:

cp -uf *.jpg /targetdir/

শেলটির সাথে মূলত একই রকম যেমন আপনি লিখেছেন:

cp -uf 1.jpg 2.jpg ... n-1.jpg n.jpg /targetdir/

যদি আপনি প্রচুর জেপিগের সাথে কাজ করে থাকেন তবে এটি খুব দ্রুত নিয়ন্ত্রণহীন হয়ে উঠতে পারে। আপনার নামকরণের সম্মেলন এবং আপনার প্রকৃতপক্ষে যে ফাইলগুলি প্রক্রিয়া করতে হবে তার উপর নির্ভর করে আপনি একবারে ডিরেক্টরিতে আলাদা সাবসেটে সিপি কমান্ড চালাতে পারেন :

cp -uf /sourcedir/[a-m]*.jpg /targetdir/
cp -uf /sourcedir/[n-z]*.jpg /targetdir/

এটি কাজ করতে পারে তবে ঠিক কতটা কার্যকর তা নির্ভর করে আপনি আপনার ফাইল তালিকাটি কীভাবে সুবিধাজনক গ্লোবাল ব্লকগুলিতে বিভক্ত করতে পারেন তার উপর ভিত্তি করে।

Globbable। আমি এই শব্দটি পছন্দ করি

কিছু কমান্ড, যেমন সন্ধান এবং xargs , ব্যথার সাথে আকারযুক্ত যুক্তি তালিকা তৈরি না করে বড় ফাইল তালিকা পরিচালনা করতে পারে।

find /sourcedir/ -name '*.jpg' -exec cp -uf {} /targetdir/ \;

-অজেক আর্গুমেন্ট প্রতিটি ফাইলের নামের সাথে {rep প্রতিস্থাপন করে খুঁজে পাওয়া প্রতিটি ফাইলের জন্য একবার কমান্ড লাইনের অবশিষ্ট অংশটি চালাবে । যেহেতু সিপি কমান্ডটি একবারে কেবল একটি ফাইলে চালিত হয়, তর্কের তালিকা সীমাটি কোনও সমস্যা নয়।

প্রতিটি ফাইল পৃথকভাবে প্রক্রিয়া করার কারণে এটি ধীর হতে পারে। এক্সগার্স ব্যবহার করা আরও কার্যকর সমাধান দিতে পারে:

find /sourcedir/ -name '*.jpg' -print0 | xargs -0 cp -uf -t /destdir/

xargs দ্বারা উপলব্ধ পূর্ণ ফাইল তালিকা গ্রহণ করতে পারেন খোঁজ , এবং এটি ভেঙ্গে সামলানো মাপ এবং রান আর্গুমেন্ট তালিকার মধ্যে CP ঐ sublists প্রতিটি উপর।

অবশ্যই, আপনার কার্নেলটি পুনরায় সংশোধন করার জন্য আরও বড় মান নির্ধারণের সম্ভাবনা রয়েছে MAX_ARG_PAGES। তবে আমি এই উত্তরে ব্যাখ্যা করতে ইচ্ছুক চেয়ে কার্নেলটি পুনরায় সংশ্লেষ করা আরও কাজ।


কেন এটিকে নিচে ভোট দেওয়া হয়েছিল তা আমার কোনও ধারণা নেই। এটি একমাত্র উত্তর যা এটি কেন ঘটছে তা ব্যাখ্যা করে বলে মনে হচ্ছে। আপনি xargsটিকে অপ্টিমাইজেশন হিসাবে ব্যবহার করার পরামর্শ দেননি বলেই হতে পারে?
ক্রিস

এক্সআরজেস সমাধানে যোগ করা হয়েছে, তবে আমি এখনও উদ্বিগ্ন হলাম যে নিম্নাঞ্চলগুলি আমার বিবরণে স্পষ্টতই কিছু ভুল হয়েছে এবং কোনটি আমাকে এটি বলতে চায় না। :(
গোল্ডপিউডো

xargsঅনেক বেশি দক্ষ বলে মনে হচ্ছে, ফলে কমান্ড কলগুলির সংখ্যা অনেক কম। আমার ক্ষেত্রে, আমি যখন ব্যবহার করি argsতখন -execফাইলগুলির সংখ্যা বাড়ানোর সাথে সলিউশনটি ব্যবহার করার সময় -12-১২ গুণ ভাল পারফরম্যান্স দেখি তা হ'ল দক্ষতা বৃদ্ধি পাচ্ছে।
জান Vlcinsky

3

এটি ঘটে কারণ আপনার ওয়াইল্ডকার্ড এক্সপ্রেশন ( *.jpg) প্রসারিত হওয়ার সময় কমান্ড লাইন আর্গুমেন্টের দৈর্ঘ্য সীমা ছাড়িয়ে গেছে (সম্ভবত আপনার কাছে প্রচুর .jpg ফাইল রয়েছে /home/ftpuser/public_html/ftparea)।

এই সীমাবদ্ধতা রোধ করার বিভিন্ন উপায় রয়েছে যেমন ব্যবহার findবা ব্যবহার করার মতো xargs। কটাক্ষপাত আছে এই নিবন্ধটি যে কাজ করতে কিভাবে আরও বিশদের জন্য।


বিষয়টিতে ভাল বাহ্যিক সংস্থার জন্য +1।
viam0Zah

3

গোল্ডপিউসো যেমন মন্তব্য করেছেন, আপনি যে প্রক্রিয়ায় প্রসারণ করছেন তাতে আপনি কতটা যুক্তি দিতে পারবেন তার সীমাবদ্ধতা রয়েছে। সেই প্যারামিটারটির ভাল বর্ণনার জন্য তার উত্তরটি দেখুন।

প্রক্রিয়াটি অত্যধিক আর্গুমেন্টটি পাস না করে বা আপনি যে আর্গুমেন্ট দিয়ে যাচ্ছেন তা হ্রাস করে আপনি সমস্যা এড়াতে পারেন।

শেলের মধ্যে লুপের জন্য একটি, সন্ধান করুন এবং এলএস, গ্রেপ এবং কিছুক্ষণ লুপ এই পরিস্থিতিতে একই কাজ করে -

for file in /path/to/directory/*.jpg ; 
do
  rm "$file"
done

এবং

find /path/to/directory/ -name '*.jpg' -exec rm  {} \;

এবং

ls /path/to/directory/ | 
  grep "\.jpg$" | 
  while
    read file
  do
    rm "$file"
  done

সবার মধ্যে একটি প্রোগ্রাম রয়েছে যা ডিরেক্টরিটি পড়ে (শেল নিজেই, সন্ধান করে এবং এলএস) এবং একটি আলাদা প্রোগ্রাম যা আসলে কার্যকরভাবে প্রতিটি আর্গুমেন্ট নেয় এবং কমান্ডের পুরো তালিকার মাধ্যমে পুনরাবৃত্তি করে।

এখন, এটি ধীর হবে কারণ * .jpg প্যাটার্নের সাথে মেলে এমন প্রতিটি ফাইলের জন্য আরএমটি কাঁটাচামচ এবং ছাড় দেওয়া দরকার।

এখানেই এক্সার্গস খেলতে আসে। xargs স্ট্যান্ডার্ড ইনপুট নেয় এবং প্রতিটি এন এর জন্য (ফ্রি বিএসডি এটি ডিফল্ট 5000 দ্বারা হয়) লাইনগুলিতে এটি এন আর্গুমেন্ট সহ একটি প্রোগ্রাম তৈরি করে। xargs হ'ল উপরের লুপগুলির একটি অপ্টিমাইজেশন কারণ আপনার কমান্ড লাইন থেকে আর্গুমেন্ট পড়ার সম্পূর্ণ ফাইলে সেট করার জন্য আপনার কেবল 1 / N প্রোগ্রামের কাঁটাচামচ করা দরকার।


2

একটি প্রোগ্রামে নির্দিষ্ট করা যেতে পারে এমন সর্বাধিক সংখ্যক যুক্তি রয়েছে, ব্যাশ সি। পি-তে অনেক আর্গুমেন্টে * .jpg প্রসারিত করে। আপনি এটি সন্ধান, এক্সার্গস বা আরএসএনসি ইত্যাদি ব্যবহার করে সমাধান করতে পারেন etc.

Xargs সম্পর্কে এখানে একবার দেখুন এবং সন্ধান করুন

/programming/143171/how-can-i-use-xargs-to-copy-files-that-have-spaces-and-quotes-in-their-names


1

'*' গ্লোব অনেকগুলি ফাইলের নামগুলিতে প্রসারিত হচ্ছে। পরিবর্তে / home / ftpuser / public_html -name '* .jpg' ব্যবহার করুন।


একই আউটপুটে * ফলাফলটি অনুসন্ধান করুন এবং প্রতিধ্বনিত করুন - এখানে কীটি শর্টের কাঁটাচামচ করার চেষ্টা করছে এমন কমান্ডটিতে সমস্ত 1 বিলিয়ন কমান্ড লাইন আর্গুমেন্টগুলি পাস না করেই xargs ব্যবহার করছে।
ক্রিস

খুব বেশি ফাইল থাকলে প্রতিধ্বনি * ব্যর্থ হবে, তবে এটি সফল হবে find এছাড়াও, + এর সাথে ফাইন্ড-এক্সেক ব্যবহার করা xargs ব্যবহারের সমতুল্য। (যদিও সবার সমর্থন + সন্ধান করেন না)
উইলিয়াম পার্সেল

1

+অপশনটি ব্যবহার করে find -execঅপারেশনটি ব্যাপকভাবে গতি বাড়িয়ে তুলবে।

find  /home/ftpuser/public_html/ftparea/ -name "*jpg" -exec cp -uf -t /your/destination "{}" +

+বিকল্প প্রয়োজন {}ব্যবহার তাই গত যুক্তি হতে -t /your/destination(অথবা --target-directory=/your/destination) এর বিকল্প cpকরে তোলে কাজ করি।

থেকে man find:

-exec কমান্ড {} +

          This  variant  of the -exec action runs the specified command on  
          the selected files, but the command line is built  by  appending  
          each  selected file name at the end; the total number of invoca  
          tions of the command will  be  much  less  than  the  number  of  
          matched  files.   The command line is built in much the same way  
          that xargs builds its command lines.  Only one instance of  ‘{}’  
          is  allowed  within the command.  The command is executed in the  
          starting directory.

সম্পাদনা করুন : সিপিতে পুনরায় সাজানো যুক্তি


আমি খুঁজে পাচ্ছি: ex -exec '/ home / ftpuser1 / public_html / ftparea / -name' * jpg '-exec cp -uf "{}" / home / ftpuser2 / public_html / ftparea / +
icelizard

আমি cpত্রুটিটি ঠিক করার জন্য যুক্তিগুলিকে পুনরায় সাজিয়েছি ।
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

1

দেখে মনে হচ্ছে আপনার কাছে *.jpgসেই ডিরেক্টরিতে অনেকগুলি ফাইল রয়েছে যাতে সেগুলি একবারে কমান্ড লাইনে ফেলে দেয়। আপনি চেষ্টা করতে পারেন:

find /home/ftpuser/public_html/ftparea1 -name '*.jpg' | xargs -I {} cp -uf {} /home/ftpuser/public_html/ftparea2/

আপনার সিস্টেমের জন্য স্যুইচটি সঠিক man xargsকিনা তা দেখতে আপনার প্রয়োগের জন্য আপনাকে পরীক্ষা করতে হবে -I

আসলে, আপনি কি সেই ফাইলগুলি ইতিমধ্যে যেখানে একই স্থানে অনুলিপি করতে চান?


আফসোস এই দুটি পৃথক ডিরেক্টরি ftpuser1 এবং ftpuser2 হওয়া উচিত
আইসেলিজার্ড

এই মাত্র চেষ্টা করেছেন: ls / home/ftpuser1/public_html/ftparea/*.jpg | xargs -আমি {} CP -uf {} / হোম / ftpuser2 / public_html / ftparea / এখনও পেয়েছিলাম -bash দিনঃ / bin / ম: আর্গুমেন্ট তালিকার অত্যন্ত দীর্ঘ
icelizard

ওহ, আপনি ঠিক বলেছেন, অবশ্যই lsএকই সমস্যা হবে! আমি বদলেছি findযা হবে না।
গ্রেগ হিউগিল

0

ফোল্ডারে যান

cd /home/ftpuser1/public_html/

এবং নিম্নলিখিতটি কার্যকর করুন:

cp -R ftparea/ /home/ftpuser2/public_html/

এইভাবে যদি 'ftparea' ফোল্ডারে সাবফোল্ডার থাকে তবে এটির একটি নেতিবাচক প্রভাব হতে পারে যদি আপনি কেবল '* .jpg' ফাইলগুলি থেকে চান তবে কোনও সাবফোল্ডার না থাকলে এই পদ্ধতির তুলনায় অবশ্যই আরও দ্রুততর হবে সন্ধান এবং xargs ব্যবহার করে

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