বাশ, কীভাবে কিছু পটভূমি প্রক্রিয়া চালানো যায় তবে অন্যের জন্য অপেক্ষা করা যায়?


11

আমি (এখনো) অন্য আছে wait, &, &&নিয়ন্ত্রণ প্রবাহ প্রশ্ন ..

বলুন আমার স্ক্রিপ্ট এরকম কিছু রয়েছে যেখানে আমি একইসাথে যতটা সম্ভব কাজ করতে চাই:

# may take some hours
something InputA > IrrelevantA &
something InputB > IrrelevantB &

# may take an hour
(
   somethingElse InputA > OutputA &
   somethingElse InputB > OutputB &
)&& combine OutputA OutputB > Result

...morestuff

প্রশ্ন 1: স্ক্রিপ্টে, combineউভয় somethingElseপ্রক্রিয়া চলাকালীন উভয় somethingপ্রক্রিয়া শেষ হওয়ার জন্য অপেক্ষা করবেন ?

প্রশ্ন 2: যদি না - এবং আমার সন্দেহ হয় না - আমি কীভাবে combineকেবল উভয় somethingElseপ্রক্রিয়াটির জন্য অপেক্ষা করতে পারি যখন somethingউপরের প্রক্রিয়াগুলি ব্যাকগ্রাউন্ডে দূরে কাজ চালিয়ে যায়?

উত্তর:


13

আপনার উদাহরণে combineসাব-শেলটি প্রস্থান করার সাথে সাথে কমান্ডটি চালানো হবে (এবং প্রদত্ত শেষ পটভূমি প্রক্রিয়াটি কোনও ত্রুটি ছাড়াই শুরু হয়েছিল)। কোনও waitআদেশ নেই বলে কাজ শুরু হওয়ার সাথে সাথে সাবশেলটি প্রস্থান করা হবে ।

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

something InputA >IrrelevantA &
something InputB >IrrelevantB &

tmp1=$(mktemp)
tmp2=$(mktemp)

( somethingElse InputA >OutputA; echo $? >"$tmp1" ) &
proc1=$!

( somethingElse InputB >OutputB; echo $? >"$tmp2" ) &
proc2=$!

wait "$proc1" "$proc2"

read ret1 <"$tmp1"
read ret2 <"$tmp2"
[ "$ret1" = 0 && "ret2" = 0 ] && combine OutputA OutputB >Result

rm "$tmp1" "$tmp2"

আপনি যদি সত্যিকার অর্থে রিটার্নের মানগুলি সম্পর্কে চিন্তা না করেন তবে আপনি কেবলমাত্র কাজগুলি সাধারণত শুরু করতে পারেন এবং ব্যবহার করতে পারেন wait:

something InputA >IrrelevantA &
something InputB >IrrelevantB &

somethingElse InputA >OutputA &
proc1=$!

somethingElse InputB >OutputB &
proc2=$!

wait "$proc1" "$proc2"
combine OutputA OutputB >Result

হাই, আমি মনে করি ২ য় বিকল্পটি আমার পক্ষে কাজ করবে ...
স্টিফেন হেন্ডারসন

3

হায় প্রক্রিয়া প্রতিকল্পন আরও দক্ষ হতে, বিশেষ করে যদি আপনি ফাইল সংরক্ষণ করতে হবে না OutputAএবং OutputBশুধুমাত্র যত্নশীল এবং Result? এই প্রবণতা বিশেষ করে সময় বাঁচানো কারণ আপনার ডিস্কে লিখিতভাবে একটি মন্থর ইনপুট / আউটপুট আছে যদি, ফাইল সংরক্ষণ হবে OutputAএবং OutputBহার সীমিত পদক্ষেপ হতে পারে?

combine  <(somethingElse InputA)  <(somethingElse InputB)  >  Result

প্রক্রিয়া প্রতিস্থাপন আপনাকে <(..here..)কোনও ফাইলের আউটপুট সংরক্ষণ করার পরিবর্তে কমান্ডটি ভিতরে রাখার অনুমতি দেয় এবং তারপরে "সম্মিলন" পদক্ষেপে ইনপুট হিসাবে এটি পড়তে পারে।

স্মৃতি যদি একটি সীমাবদ্ধতা হয় outputAএবং outputBমেমরিটি যা ধারণ করতে পারে তার চেয়ে বেশি এবং এর আকার আরও বেশি হয়, তবে এটি কী পুরো উদ্দেশ্যকে পরাস্ত করবে?

হবে combineউভয় প্রসেস সম্পন্ন পর্যন্ত আগেই চলমান শুরু অপেক্ষা করবেন?


এটি "বিপদ" নয়; দয়া করে না না ফ্রেজ একটা প্রশ্ন আকারে আপনার প্রতিক্রিয়া। সিরিয়াসলি, আপনি একটি নতুন ধারণা নিয়ে এসেছেন এবং আমি মনে করি এটি বেশ ভাল। আপনার কয়েকটি বিষয়কে প্রতিক্রিয়া জানাতে: combineদুটি somethingElseকমান্ড শুরু হওয়ার সাথে সাথেই চলতে শুরু করবে, তবে এটি ঠিক আছে, কারণ <(…)জিনিসগুলি পাইপ; সুতরাং combineযদি somethingElseপ্রক্রিয়াগুলি ছাড়িয়ে যায় তবে কেবলমাত্র ডেটার জন্য অপেক্ষা করতে বাধ্য করা হবে । এবং, কারণ তারা পাইপ, আকার কোনও সমস্যা নয়। … (চালিয়ে যাওয়া)
জি-ম্যান বলছেন '

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

2

আপনি waitকমান্ডটি ব্যবহার করতে পারেন :

(echo starting & sleep 10 & wait) && echo done

আপনি দেখতে পাবেন যে "শুরু করা" লাইনটি এখনই ঘটে যায় এবং "সম্পন্ন" 10 সেকেন্ডের জন্য অপেক্ষা করে।


সাধারণত অপেক্ষা একই শেলের শিশু প্রক্রিয়াগুলির প্রয়োজন requires সেখানে অপেক্ষা খুব সুন্দর।
মাইকজার্ভ

1
@ মাইকজার্, আপনি কী সম্পর্কে কথা বলছেন? মূল বিষয়: এটি সেই সাবহেলের সমস্ত সন্তানের জন্য অপেক্ষা করে।
psusi

আমার প্রাথমিক পরীক্ষার দ্বারা এটি কাজ করে। আমি এখন এটি বড় স্ক্রিপ্টে চেষ্টা করতে যাচ্ছি
স্টিফেন হেন্ডারসন

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

0

আমি বাস্তবে ঠিক এখানে প্রদর্শন করেছি যে এই ধরণের জিনিসটি এখানে অন্য উত্তরে কীভাবে করা যেতে পারে । এই উত্তরটি একটি ব্যাকগ্রাউন্ড প্রক্রিয়া দ্বারা 2 লগগুলি রক্ষণাবেক্ষণ করা নিশ্চিত করার বিষয়ে একটি প্রশ্নের উত্তর ছিল, তাই আমি এটি 10 ​​দিয়ে দেখিয়েছি।

ডেমো স্ক্রিপ্ট

cat <<-\DEMO >|${s=/tmp/script} 
printf 'tty is %s\nparent pid is %s\npid is pid=%s\n' \
     "$(tty)" "$PPID" "$$"
exec 1>&2 ; nums=$(seq 0 9)
rm ${files=$(printf "/tmp/file%s\n" $nums)}
for n in $nums ; do { for f in $files ; do
    echo "Line $n" >>"$f" ; done
sleep 1 ; } ; done
#END
DEMO

ডেমো চালান

s=/tmp/script ;chmod +x $s ;info="$(($s &)2>&- &)"
echo "$info" ; pid="${info##*=}" ; echo
while ps -p $pid >/dev/null ; do sleep 3 ; done
for f in /tmp/file[0-9] ; do
    printf 'path : %s\tline count : %s\n' \
        $f $(<$f wc -l)
done

আউটপুট:

tty is not a tty
parent pid is 1
pid is 12123

path : /tmp/file0    line count : 10
path : /tmp/file1    line count : 10
path : /tmp/file2    line count : 10
path : /tmp/file3    line count : 10
path : /tmp/file4    line count : 10
path : /tmp/file5    line count : 10
path : /tmp/file6    line count : 10
path : /tmp/file7    line count : 10
path : /tmp/file8    line count : 10
path : /tmp/file9    line count : 10

উপরোক্ত দেখায় এটা তোলে তৈরী করে এবং রান নামে একটি স্ক্রিপ্ট /tmp/script, chmod'গুলি এক্সিকিউটেবল যেমন, আর তাতে রান &backgroundA -এর &backgrounded ( subshell )

স্ক্রিপ্ট rms /tmp/file0-910 ফাইল এবং echoesপ্রতি 10 সেকেন্ডে সেগুলিতে 10 টির জন্য একটি লাইন। আমি $infoঅস্বীকার করা প্রক্রিয়া থেকে কিছু ক্যাপচার করি এবং এটি ক্যাপচারের $(command substitution). While psবিষয়ে এখনও রিপোর্টের মাধ্যমে উপস্থাপন করি $pid, আমি জানি এটি এখনও চলছে তাই আমি sleep.যখন এটি শেষ হয় তখন সমস্ত 10 টি ফাইলের লাইনগুলি গণনা করা হয়wc.

আপনি কোনও প্রক্রিয়াটি এভাবে শুরু করার পরে আপনি নির্ধারিতভাবে এর মূল পিতামহীন প্রক্রিয়াটি বন্ধ করতে পারেন এবং এটি ট্রাক চালিয়ে যাবে - এটি কার্যকরভাবে অস্বীকার করা হয়েছে। এটাও মানে আপনি প্রচলিত ব্যবহার করতে পারবেন না waitকমান্ড, কিন্তু অপেক্ষায় ps'র আগমন কোনো ক্ষেত্রে আরো জোরালো হওয়া উচিত।

উল্লেখযোগ্য, আমি মনে করি, প্রক্রিয়াটি আসলে প্রাথমিকভাবে ডেকে আনা হয় $(command substitution)এবং printfsআমি যে $infoআমি চাই তাই কার্যকরভাবে এটি নিয়ন্ত্রণ করতে পারি। তবে এটির সাথে তার টার্মিনাল আউটপুটটি ড্রপ হওয়ার সাথে সাথে exec 1>&2(যা একই সাবশেলে বন্ধ রয়েছে 2>&-), প্রক্রিয়াটি পালিয়ে যায় এবং আমাকে অন্য প্রান্তে এটির জন্য অপেক্ষা করতে হবে। উভয় বিশ্বের সেরা কিন্ডা, বিশেষত আপনি যদি ইনপুট পাইপগুলি হ্যান্ডেল করতে ব্যবহার করেন, তবে যতক্ষণ আপনি আপনার মনকে সমস্ত পুনঃনির্দেশ এবং প্রক্রিয়া নেতাদের চারপাশে গুটিয়ে রাখতে পারেন।

অন্য সব কিছুই এখানে প্রদর্শনের জন্য। আপনার এটি চালানোর জন্য যা দরকার তা হ'ল শীর্ষস্থানীয় স্ক্রিপ্ট এবং:

info="$(($script_path &)2>&- &)"    

দ্রষ্টব্য: এটি কেবলমাত্র টার্মিনালে প্রিন্ট করে আমি ঠিক এটি প্রদর্শন করতে চাইছিলাম। $PPID,এই প্রক্রিয়াদ্বারা উল্লিখিত হিসাবেএই প্রক্রিয়াটি টার্মিনাল দ্বারা অস্বীকার করা হয় এবং এর প্রত্যক্ষ শিশু$PID 1.

আপনি যদি এই দুটি দুটি একযোগে চালাতে চান এবং তাদের জন্য অপেক্ষা করতে পারেন তবে আপনি কেবল psতাদের উভয় পিড হস্তান্তর করতে এবং অপেক্ষা করতে পারেন।

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