সমান্তরালে বাশ স্ক্রিপ্ট সীমিত সংখ্যক কমান্ডের প্রক্রিয়াজাতকরণ


196

আমার কাছে বাশ স্ক্রিপ্ট রয়েছে যা দেখতে এটির মতো দেখাচ্ছে:

#!/bin/bash
wget LINK1 >/dev/null 2>&1
wget LINK2 >/dev/null 2>&1
wget LINK3 >/dev/null 2>&1
wget LINK4 >/dev/null 2>&1
# ..
# ..
wget LINK4000 >/dev/null 2>&1

কমান্ড শেষ না হওয়া অবধি প্রতিটি লাইনের প্রক্রিয়াজাতকরণের পরে পরবর্তী একের দিকে চলে যাওয়া খুব সময়সাপেক্ষ, আমি উদাহরণস্বরূপ 20 লাইনগুলি একবারে প্রক্রিয়া করতে চাই যখন তারা শেষ হয় অন্য 20 টি লাইন প্রক্রিয়াজাত হয়।

আমি wget LINK1 >/dev/null 2>&1 &ব্যাকগ্রাউন্ডে কমান্ডটি প্রেরণ এবং চালিয়ে যাওয়ার কথা ভেবেছিলাম , তবে এখানে 4000 টি লাইন রয়েছে এর অর্থ আমার পারফরম্যান্স সংক্রান্ত সমস্যা হবে, একই সাথে আমার কতগুলি প্রক্রিয়া শুরু করতে হবে তা সীমাবদ্ধ থাকার কথা উল্লেখ না করে এটি ভাল নয় ধারণা.

একটি সমাধান যা আমি এই মুহূর্তে ভাবছি তা যাচাই করা হয় যে কোনও একটি আদেশ এখনও চলমান আছে কি না, উদাহরণস্বরূপ 20 লাইনের পরে আমি এই লুপটি যুক্ত করতে পারি:

while [  $(ps -ef | grep KEYWORD | grep -v grep | wc -l) -gt 0 ]; do
sleep 1
done

অবশ্যই এই ক্ষেত্রে আমি যুক্ত করতে হবে এবং লাইনটির শেষদিকে! তবে আমি অনুভব করছি এটি করার সঠিক উপায় এটি নয়।

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


1
waitএখানে সঠিক উত্তর, তবে আপনার while [ $(ps …লেখাটি আরও ভাল লেখা হবে while pkill -0 $KEYWORD…- প্রোক্টোলগুলি ব্যবহার করে … এটি বৈধ কারণে কোনও নির্দিষ্ট নামের প্রক্রিয়া এখনও চলছে কিনা তা যাচাই করার জন্য legitimate
কোজিরো

আমি মনে করি এই প্রশ্নটি আবার খোলা উচিত। "সম্ভাব্য সদৃশ" কিউএ সমান্তরালভাবে সীমাবদ্ধ সংখ্যক প্রোগ্রাম চালানো । 2-3 কমান্ডের মত। এই প্রশ্নটি অবশ্য চলমান কমান্ডগুলিতে যেমন লুপের দিকে দৃষ্টি নিবদ্ধ করে। (দেখুন "তবে 4000 লাইন রয়েছে")
ভ্যাসিলিনভিকভ

@ ভাস্যনাভিকভ আপনি কি এই প্রশ্ন এবং সদৃশ উভয়ের সমস্ত উত্তর পড়েছেন ? এখানে এই প্রশ্নের প্রত্যেকটি উত্তর, সদৃশ প্রশ্নের উত্তরগুলিতেও পাওয়া যাবে। যে অবিকল একটি ডুপ্লিকেট প্রশ্নই সংজ্ঞা। আপনি কোনও লুপে কমান্ডগুলি চালাচ্ছেন কিনা তা একেবারেই কোনও পার্থক্য করে না।
রবিন্টিস

@robinCTS- এ ছেদ রয়েছে তবে প্রশ্নগুলি নিজেরাই আলাদা। এছাড়াও, লিঙ্কযুক্ত কিউএর 6 টির মধ্যে সর্বাধিক জনপ্রিয় 6 টি উত্তর কেবলমাত্র 2 টি প্রক্রিয়াগুলির সাথে।
ভাসিলিনভিকভ

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

উত্তর:


331

waitঅন্তর্নির্মিতটি ব্যবহার করুন :

process1 &
process2 &
process3 &
process4 &
wait
process5 &
process6 &
process7 &
process8 &
wait

উপরের উদাহরণের জন্য, 4 প্রক্রিয়া process1... process4পটভূমিতে শুরু হবে এবং পরবর্তী সেটটি শুরু করার আগে শেলগুলি শেষ না হওয়া পর্যন্ত অপেক্ষা করবে।

থেকে গনুহ ম্যানুয়াল :

wait [jobspec or pid ...]

প্রতিটি প্রক্রিয়া আইডি পিড বা জব স্পেসিফিকেশন জবস্পেক প্রস্থান করে নির্দিষ্ট শিশু প্রক্রিয়াটি না হওয়া পর্যন্ত অপেক্ষা করুন এবং অপেক্ষা করা শেষ কমান্ডের প্রস্থান স্থিতি ফিরে আসুন। যদি কোনও কাজের বৈশিষ্ট্য দেওয়া হয়, তবে কাজের সমস্ত প্রক্রিয়াগুলির জন্য অপেক্ষা করা হয়। যদি কোনও যুক্তি না দেওয়া হয় তবে বর্তমানে সমস্ত সক্রিয় শিশু প্রক্রিয়াগুলির জন্য অপেক্ষা করা হচ্ছে, এবং প্রত্যাবর্তনের অবস্থা শূন্য। যদি জবস্পেক বা পিড উভয়ই শেলের একটি সক্রিয় শিশু প্রক্রিয়া নির্দিষ্ট করে না, তবে রিটার্নের স্থিতি 127।


14
তাই মূলতi=0; waitevery=4; for link in "${links[@]}"; do wget "$link" & (( i++%waitevery==0 )) && wait; done >/dev/null 2>&1
কোজিরো

18
আপনি নিশ্চিত না হন যে প্রতিটি প্রক্রিয়া ঠিক একই সময়ে শেষ হবে, এটি একটি খারাপ ধারণা। বর্তমান মোট কাজগুলি একটি নির্দিষ্ট টুপি রাখতে আপনার নতুন কাজ শুরু করা দরকার .... সমান্তরাল উত্তর এটি।
26

1
লুপে এটি করার কোনও উপায় আছে?
ডোমেনগুলি

আমি এটি চেষ্টা করেছি তবে মনে হয় যে একটি ব্লকে করা ভেরিয়েবল অ্যাসাইনমেন্টগুলি পরবর্তী ব্লকে উপলব্ধ নয়। এগুলি কি কারণ তারা পৃথক প্রক্রিয়া? ভেরিয়েবলগুলি মূল প্রক্রিয়াটিতে ফিরে যাওয়ার কোনও উপায় আছে কি?
ববি

97

সমান্তরাল দেখুন । এটির বাক্য গঠন একই রকম xargs, তবে এটি সমান্তরালভাবে কমান্ডগুলি চালায়।


13
এটি ব্যবহারের চেয়ে ভাল wait, যেহেতু এটি পুরানোগুলি সম্পূর্ণ হিসাবে নতুন কাজ শুরু করার বিষয়ে যত্ন নেয়, পরবর্তী শুরুর আগে পুরো ব্যাচ শেষ করার অপেক্ষা না করে।
চ্যানার

5
উদাহরণস্বরূপ, যদি আপনার কোনও ফাইলে লিঙ্কগুলির তালিকা থাকে তবে আপনি এটি করতে পারেন cat list_of_links.txt | parallel -j 4 wget {}যা wgetএকবারে চারটি চালিয়ে যাবে।
মিঃ ললামা

5
শহরে পেক্সেক নামে একটি নতুন বাচ্চা রয়েছে যা এর পরিবর্তে প্রতিস্থাপন parallel
স্ল্যাশবিন

2
একটি উদাহরণ প্রদান আরো সহায়ক হবে
jterm

1
parallel --jobs 4 < list_of_commands.sh, যেখানে list_of_commands.sh হ'ল প্রতিটি লাইনে একটি একক কমান্ড (যেমন wget LINK1, দ্রষ্টব্য নোট &) সহ একটি ফাইল । যা করতে হবে পারে CTRL+Zএবং bgপরে এটি ব্যাকগ্রাউন্ডে চলতে থাকুক।
weiji14

71

আসলে, xargs আপনার জন্য সমান্তরালভাবে কমান্ডগুলি চালাতে পারে । তার জন্য একটি বিশেষ -P max_procsকমান্ড-লাইন বিকল্প রয়েছে। দেখুন man xargs


2
+100 এটি দুর্দান্ত কারণ এটি নির্মিত হয়েছে এবং এটি ব্যবহার করা খুব সহজ এবং এটি ওয়ান-লাইনারে করা যেতে পারে
ক্লে

ছোট পাত্রে ব্যবহার করার জন্য দুর্দান্ত, কারণ কোনও অতিরিক্ত প্যাকেজ / নির্ভরতার প্রয়োজন নেই!
মার্কো রায়

1
উদাহরণস্বরূপ এই প্রশ্নটি দেখুন: স্ট্যাকওভারফ্লো
মার্কো রায়

7

আপনি 20 টি প্রক্রিয়া চালাতে পারেন এবং কমান্ডটি ব্যবহার করতে পারেন:

wait

আপনার সমস্ত পটভূমি কাজ শেষ হয়ে গেলে আপনার স্ক্রিপ্টটি অপেক্ষা করবে এবং চালিয়ে যাবে।

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