جميع الأمثلة مكتوبة بلغة bash ، لكن (مع الحد الأدنى من التغييرات) ستعمل في ksh. لدى Csh أيضًا وسيلة لإدارة العمليات الخلفية ، لذلك يمكن أيضًا استخدام نهج مماثل.
التحكم في الوظيفة
هذا هو اسم القسم في man bash حيث تذهب التفاصيل ، في حال كنت تحب قراءة الرجل. نستخدم الميزات البسيطة التالية:
الأمر & - يقوم بتشغيل أمر في
وظائف الخلفية - يطبع قائمة بأوامر الخلفية
مثال بسيط لا يقوم بأي إجراء مفيد. تتم قراءة الأرقام من ملف test.txt ، ويتم تشغيل 3 عمليات بالتوازي ، والتي تنام لعدد الثواني المقابل. كل ثلاث ثوان ، يتم فحص عدد العمليات الجارية ، وإذا كان هناك أقل من ثلاث ، يتم بدء عملية جديدة. تم نقل عملية تشغيل الخلفية إلى وظيفة منفصلة mytask ، ولكن يمكنك البدء بها مباشرة في حلقة.
test.sh
#!/bin/bash
NJOBS=3 ; export NJOBS
function mytask () {
echo sleeping for $1
sleep $1
}
for i in $( cat test.txt )
do
while [ $(jobs | wc -l ) -ge $NJOBS ]
do
sleep 3
done
echo executing task for $i
mytask $i &
done
echo waiting for $( jobs | wc -l ) jobs to complete
wait
ادخال البيانات:
test.txt
60
50
30
21
12
13
50
30
21
12
13
انتبه إلى الانتظار بعد الحلقة ، ينتظر الأمر حتى تنتهي العمليات التي تعمل في الخلفية. بدونها ، سيتم إنهاء البرنامج النصي فور انتهاء الحلقة وستتوقف جميع عمليات الخلفية. ربما تم ذكر هذا الانتظار في الميم الشهير "أوه ، انتظر !!!".
إنهاء عمليات الخلفية
إذا قاطعت النص باستخدام Ctrl-C ، فسيتم إعدامه مع جميع عمليات الخلفية. تستقبل جميع العمليات التي تعمل في الجهاز إشارات من لوحة المفاتيح (على سبيل المثال ، SIGINT). إذا تم قتل البرنامج النصي من محطة أخرى باستخدام الأمر kill ، فستظل عمليات الخلفية قيد التشغيل حتى الإنهاء ، وتحتاج إلى تذكر ذلك.
رأس سبويلر
user@somehost ~/tmp2 $ ps -ef | grep -E «test|sleep»
user 1363 775 0 12:31 pts/5 00:00:00 ./test.sh
user 1368 1363 0 12:31 pts/5 00:00:00 ./test.sh
user 1370 1368 0 12:31 pts/5 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 60
user 1373 1363 0 12:31 pts/5 00:00:00 ./test.sh
user 1375 1373 0 12:31 pts/5 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 50
user 1378 1363 0 12:31 pts/5 00:00:00 ./test.sh
user 1382 1378 0 12:31 pts/5 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 30
user 1387 1363 0 12:31 pts/5 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 3
user 1389 556 0 12:31 pts/2 00:00:00 grep --colour=auto -E test|sleep
user@somehost ~/tmp2 $ kill 1363
user@somehost ~/tmp2 $ ps -ef | grep -E «test|sleep»
user 1368 1 0 12:31 pts/5 00:00:00 ./test.sh
user 1370 1368 0 12:31 pts/5 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 60
user 1373 1 0 12:31 pts/5 00:00:00 ./test.sh
user 1375 1373 0 12:31 pts/5 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 50
user 1378 1 0 12:31 pts/5 00:00:00 ./test.sh
user 1382 1378 0 12:31 pts/5 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 30
user 1399 556 0 12:32 pts/2 00:00:00 grep --colour=auto -E test|sleep
user 1363 775 0 12:31 pts/5 00:00:00 ./test.sh
user 1368 1363 0 12:31 pts/5 00:00:00 ./test.sh
user 1370 1368 0 12:31 pts/5 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 60
user 1373 1363 0 12:31 pts/5 00:00:00 ./test.sh
user 1375 1373 0 12:31 pts/5 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 50
user 1378 1363 0 12:31 pts/5 00:00:00 ./test.sh
user 1382 1378 0 12:31 pts/5 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 30
user 1387 1363 0 12:31 pts/5 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 3
user 1389 556 0 12:31 pts/2 00:00:00 grep --colour=auto -E test|sleep
user@somehost ~/tmp2 $ kill 1363
user@somehost ~/tmp2 $ ps -ef | grep -E «test|sleep»
user 1368 1 0 12:31 pts/5 00:00:00 ./test.sh
user 1370 1368 0 12:31 pts/5 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 60
user 1373 1 0 12:31 pts/5 00:00:00 ./test.sh
user 1375 1373 0 12:31 pts/5 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 50
user 1378 1 0 12:31 pts/5 00:00:00 ./test.sh
user 1382 1378 0 12:31 pts/5 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 30
user 1399 556 0 12:32 pts/2 00:00:00 grep --colour=auto -E test|sleep
يمكن التعامل مع هذا الموقف عن طريق اعتراض الإشارات الضرورية ، والتي نضيف لها معالجًا في بداية البرنامج النصي:
فخ
function pids_recursive() {
cpids=`pgrep -P $1|xargs`
echo $cpids
for cpid in $cpids;
do
pids_recursive $cpid
done
}
function kill_me () {
kill -9 $( pids_recursive $$ | xargs )
exit 1
}
#
#trap 'echo trap SIGINT; kill_me ' SIGINT
trap 'echo trap SIGTERM; kill_me' SIGTERM
يعرض kill -L قائمة بالإشارات الموجودة ، إذا لزم الأمر ، يمكنك إضافة معالجات للإشارات المطلوبة.