কোনও স্ক্রিপ্টকে বাঁচিয়ে রাখতে "সত্য থাকা অবস্থায়" ব্যবহার করা কি একটি ভাল ধারণা?


19

আমি কেবল একটি ভিন্ন বিশ্ব থেকে ইউনিক্সে ঝাঁপ দিচ্ছি, এবং জানতে চাইছিলাম

while true
do
  /someperlscript.pl
done

পার্ল স্ক্রিপ্ট নিজেই অভ্যন্তরীণভাবে একটি ফোল্ডার / ফাইল পর্যবেক্ষক রয়েছে যা ফাইলগুলি টার্গেটের স্থানে পরিবর্তন করা হলে কার্যকর করে।

এটি ( while true) একটি ভাল ধারণা? যদি তা না হয় তবে পছন্দসই দৃust় পদ্ধতির কী?

টিয়া

সম্পাদনা: যেহেতু এটি মোটামুটি আগ্রহ তৈরি করেছে বলে মনে হচ্ছে, এখানে সম্পূর্ণ দৃশ্যাবলী। পার্ল স্ক্রিপ্ট নিজেই একটি ফাইল ওয়াচার ব্যবহার করে একটি ডিরেক্টরি দেখে। নতুন ফাইলগুলি পাওয়ার পরে (তারা আরএসসিএনসি দিয়ে আসে) এটি নতুনটিকে তুলে ধরে এটি প্রক্রিয়া করে। এখন আগত ফাইলগুলি দূষিত হতে পারে (জিজ্ঞাসা করবেন না ... একটি রাস্পবেরি পাই থেকে আসছে), এবং কখনও কখনও প্রক্রিয়া এটি মোকাবেলা করতে সক্ষম নাও হতে পারে। আমি ঠিক জানি না কেন, কারণ আমরা এখনও সমস্ত পরিস্থিতি সম্পর্কে অবগত নই।

তবে - যদি প্রক্রিয়াটি কোনও কারণে ব্যর্থ হয়, আমরা চাই এবং এটি চলমান হোক এবং পরবর্তী ফাইলটি মোকাবেলা করুক, কারণ পরবর্তী ফাইলটি পূর্ববর্তী ফাইলটির সাথে সম্পূর্ণ সম্পর্কিত নয় যা ত্রুটির কারণ হতে পারে।

সাধারণত আমি কিছু ধরণের ক্যাচ ব্যবহার করতাম এবং পুরো কোডটি চারপাশে মোড়ানো করতাম যাতে এটি ক্র্যাশ না হয়। তবে পার্লের জন্য নিশ্চিত ছিল না।

আমি যা বুঝতে পেরেছি সে থেকে সুপারভাইজারের মতো কিছু ব্যবহার করা এটির জন্য একটি ভাল পদ্ধতির।


9
এই লিনাক্স নাকি ইউনিক্স? যদি এটি লিনাক্স হয় তবে আপনি সম্ভবত inotifyAPI টি পরীক্ষা করতে চান যাতে আপনি আপনার টার্গেট ডিরেক্টরিতে ফাইল পরিবর্তনের জন্য অপেক্ষা করা ব্যস্ত লুপ এড়াতে পারেন।
রোয়াইমা

এর লিনাক্স, উবুন্টু
অভিনব গুজ্জার

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

উত্তর:


21

পার্ল স্ক্রিপ্টটি কত দ্রুত ফিরে আসে তার উপর এটি নির্ভর করে। যদি এটি দ্রুত ফিরে আসে, আপনি সিপিইউ লোড এড়াতে মৃত্যুদণ্ড কার্যকর করার মধ্যে একটি ছোট বিরতি sertোকাতে চাইতে পারেন, যেমন:

while true
do
  /someperlscript.pl
  sleep 1
done

স্ক্রিপ্টটি পাওয়া না গেলে বা তত্ক্ষণাত ক্রাশ হয়ে গেলে এটি সিপিইউ হগকেও প্রতিরোধ করবে।

এই সমস্যাগুলি এড়াতে লুপটি আরও ভালভাবে পার্ল স্ক্রিপ্টে প্রয়োগ করা যেতে পারে।

সম্পাদনা:

আপনি যে লুপটি লিখেছেন তার উদ্দেশ্য হ'ল পার্ল স্ক্রিপ্টটি ক্র্যাশ হওয়ার পরে পুনরায় চালু করা, এটি একটি তদারকি পরিষেবা হিসাবে কার্যকর করা তবে এটি করার সঠিক উপায়টি ওএস নির্ভর is উদাহরণস্বরূপ: সোলারিস এসএমএফ, লিনাক্স সিস্টেমড বা ক্রোন ভিত্তিক পুনরারম্ভকারী।


10
আপনি while sleep 1; do ...সত্য কলটি সংরক্ষণ করতে পারেন ।
রাফেল আহরেন্স

4
@ রাফেলআহরেনস যদিও এটি প্রাথমিক আচরণে কিছুটা পরিবর্তন আনবে। until ! sleep 1; do ...; doneস্ক্রিপ্টটি অবিলম্বে শুরু করার সময় বিকল্পটি সেই বিল্টিন কলটি সংরক্ষণ করবে save
jlliagre

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

2
উন্নত: sleep 1& /someperlscript.pl; wait
ব্যবহারকারী23013

2
পছন্দ করেছেন টিবিএইচ, আমি কখনই untilনির্দেশ ব্যবহার করি না , আমি এটিকে একটি অনুমানমূলক do/untilলুপ দিয়ে বিভ্রান্ত করেছি যা শেলের মধ্যে নেই।
jlliagre

13

ব্যবহার সম্পর্কে অন্যান্য উত্তরগুলি inotifyসঠিক, তবে এই প্রশ্নের উত্তর নয়।

একটি প্রক্রিয়া সুপারভাইজার, যেমন supervisord, upstartঅথবা runit, ঠিক পর্যবেক্ষক এবং একটি সেবা পুনরায় চালু হলে ক্র্যাশের সমস্যার জন্য ডিজাইন করা হয়েছে।

আপনার ডিস্ট্রো সম্ভবত অন্তর্নির্মিত একটি প্রক্রিয়া সুপারভাইজার নিয়ে আসে।


11

while trueসাধারণ উদ্দেশ্যে "চিরকাল লুপ" নির্মাণ হিসাবে ভাল। অন্য উত্তরগুলি যেমন বলেছে, লুপটির দেহটি খালি হওয়া উচিত নয়, বা লুপের ভিতরে থাকা কমান্ডটি খালি হওয়া উচিত নয় not

আপনি যদি লিনাক্স ব্যবহার করে থাকেন তবে আপনি যেমন একটি কমান্ড ব্যবহার করতে চাইতে পারেন inotifywaitযা whileলুপটিকে আরও সহজ করে তোলে :

while inotifywait -qqe modify "$DIRECTORY"
do
    process_the_directory "$DIRECTORY"
done

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


`(অ্যাপটি-গেট বা ইয়াম) ইনোটাইফাই-সরঞ্জামগুলি ইনস্টল করুন` +1 দুর্দান্ত!
জাজাও

4

পার্ল স্ক্রিপ্টে 1 টি সরান (@ রাইমা পরামর্শ অনুসরণ করে)

#!/usr/bin/perl

 use Linux::Inotify2;

 my $inotify = new Linux::Inotify2 or die "unable to inotify: $!";

 $inotify->watch ("Dir", IN_MODIFY, ## or in_{acess,create,open, etc...}
   sub { my $e = shift;
     my $name = $e->fullname;
     ## whatever 
     print "$name was modified\n" if $e->IN_MODIFY;
  });

 1 while $inotify->poll;

1
স্ক্রিপ্ট ক্র্যাশ হওয়া বা কোনও কারণে নিহত হওয়ার পরে এটি পুনরায় আরম্ভের প্রয়োজনীয়তার বিষয়টি বিবেচনা করে না।
jlliagre

@ জেলিয়াগ্রে, মন্তব্যের জন্য ধন্যবাদ উত্তরে আমি ক্র্যাশ বা হত্যার পরে উদ্দেশ্যমূলক আচরণের জন্য স্পষ্ট স্পেসিফিকেশন দেখতে পাচ্ছি না। এটি স্পষ্টতই একটি আকর্ষণীয় এবং প্রাসঙ্গিক প্রশ্ন। এই মুহুর্তের জন্য আমি এটিকে সহজ রাখব (স্ক্রিপ্টটি মারা গেলে বা নিহত হলে মৃত থাকুন :)
জয়াওও

@ jlliagre- এর ব্যতিক্রমগুলি এটাই। তবে পার্ল এ জাতীয় ক্ষেত্রে সবচেয়ে উপযুক্ত পছন্দ নাও হতে পারে কারণ এটি ব্যতিক্রম ব্যবস্থাকে সমর্থন করে না। শুধু অনুমান। স্ক্রিপ্টটি এমন কোনও ভাষায় পোর্ট করা ভাল যা ব্যতিক্রমগুলি সমর্থন করে। এটি সমস্ত নির্ভর করে অবশ্যই পোর্টিংয়ের কাজটি কত বড়।

@ নাশা, পার্লে, সিগন্যাল হ্যান্ডলার, ত্রুটি ভেরিয়েবল, টাইর :: ক্ষুদ্র ইত্যাদি সহ আমরা এটি করতে পারি! ... তবে - আমি ব্যতিক্রম হ্যান্ডলিং এবং ত্রুটি পুনরুদ্ধারকে ঘৃণা করি: এগুলি কখনই সম্পূর্ণ হয় না ...
জাজোও

1
@ জাজোও আমি ত্রুটি পুনরুদ্ধার খুব কমই সম্পন্ন হয়েছে যে বিষয়ে আপনার সাথে একমত। সম্ভাব্য সমস্ত কেস কভার করা অবশ্যই বিকাশকারীদের উপর নির্ভর করে। শিল্প বিশ্বের পিএলসিগুলির সাথে কি এটি অতএব এটি অবশ্যই বেশ কিছুটা অবশ্যই সম্ভব ;-)।

3

যখন আপনার পার্ল স্ক্রিপ্টটি সর্বদা চলতে থাকবে, তখন কেন নির্মাণের সময় ব্যবহার করবেন? যখন পার্ল কিছু গুরুতর সমস্যা দেখার জন্য ব্যর্থ হয়, তখন নতুন পার্ল স্ক্রিপ্টটি শুরু হয়ে যায় ঠিক ততই শক্ত হয়ে ক্র্যাশ হয়ে যায়। আবার-ও-আবার-ও-তাই অন।
যদি আপনি সত্যিই আপনার পার্ল শুরু করতে চান তবে ক্রন্টব এবং একটি স্ক্রিপ্ট বিবেচনা করুন যা প্রথমে চলমান দৃষ্টান্তগুলির জন্য পরীক্ষা করে। এইভাবে আপনার স্ক্রিপ্টটি পুনরায় বুট করার পরেও শুরু হবে।


2

সাধারণভাবে while trueএটি ব্যবহার করতে সমস্যা নেই কারণ এটি একটি ক্ষুদ্র পরীক্ষা যা কেবল পার্ল স্ক্রিপ্টটি শেষ হওয়ার পরে কার্যকর করা হয়। মনে রাখবেন যে আপনি যে লিনাক্স / ইউনিক্স বৈকল্পিকটি ব্যবহার করছেন তার উপর নির্ভর করে স্ক্রিপ্টটি লগ অফের সময় শেষ হতে পারে। এই ক্ষেত্রে কোনও স্ক্রিপ্টে লুপটি ব্যবহার করে বিবেচনা করুন এবং এটিকে কল করুন nohupএবং এটি পটভূমিতে রাখুনnohup myscript &

যদি পার্ল স্ক্রিপ্টটি প্রায়শই বন্ধ হয়ে যায় এবং সিপিইউ লোডের কারণ হয়ে থাকে তবে এই লোডটি পার্ল স্ক্রিপ্টের জন্য দায়বদ্ধ এবং না while true

আরও দেখুন man nohupবিস্তারিত জানার জন্য।


একমাত্র সমস্যা হ'ল হট লুপের সম্ভাব্যতা যা সিপিইউ ব্যবহার চালিয়ে যায়। সুতরাং আমি লুপটির নিচে ঘুমের ডাক দেওয়ার সাথে সম্পূর্ণরূপে একমত।
ক্রেগ

2

আপনি যদি কোনও প্রক্রিয়া পরিচালনা করতে চান তবে আপনি এটি করতে কোনও প্রক্রিয়া পরিচালককে সন্ধান করতে পারেন।

সম্প্রতি বহু সিস্টেমের সাথে, আপনি ব্যবহার করতে পারেন systemd আপনার প্রসেস (যা শাস্ত্রীয় Init-স্ক্রিপ্ট উপর systemd হল সুবিধাগুলো এক) নিরীক্ষণ করতে। আপনার পছন্দের ডিস্ট্রো systemd ব্যবহার না হওয়া করলে, আপনি ব্যবহার করতে পারে daemontools বা monit


monএকটি সহজ বিকল্প, যদি মনিট এবং সিস্টেমডের ভারী বিশালত্ব যদি তারা আমাকে যতটা বিরক্ত করে।
আনকো

2

whileলুপ সত্যিই একটি ভাল ধারণা না। সেখানে কোনও রেহাই নেই - এটি কেবল চিরকাল চলে - স্থিরভাবে । যে কোনও সংখ্যক জিনিস পরিবেশে পরিবর্তিত হতে পারে এবং এটি প্রভাবিত হবে না - এবং এটি খারাপ হতে পারে।

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

এবং যদি স্বর্গকে নিষেধ করা হয় তবে সেই লুপটি চলমান শেলের যে কোনও জায়গায় মেমরি ফাঁস হয় - এমনকি সবচেয়ে মিনিটও - স্থিরভাবে এটি ফাঁস হতে থাকবে । এটি অচিহ্নবদ্ধ তৈরি করবে এবং একমাত্র অবলম্বন হ'ল জোর করে এটিকে হত্যা করা, তারপরে এটি পরে শুরু করার জন্য শুরু করুন।

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

উদাহরণস্বরূপ, যদি আপনার perlস্ক্রিপ্টটি কিছু তদারকি করা ডিরেক্টরিতে কোনও ফাইল পরিবর্তন সফলভাবে পরিচালনা করার পরে সত্যায় ফিরে আসে:

#!/bin/sh
trap 'rm -rf -- "${ldir%%*.}"' 0 INT
_exec() case    $#      in
        (0)     exec env -  "PID=$$" "ldir=${TMPDIR:-/tmp}/." \
                            "$0" "$@";;
        (*)     export "$@" "boff=0" "lmt=30"
                exec        "$0" "$@";;
        esac
[ "$PID" = "$$" ] || _exec
[ -w "$ldir" ]  &&
case    $ldir   in
(*.)    until   mkdir -- "$ldir"
        do      :& ldir=$ldir$$$!
        done    2>/dev/null
;;
(*)     until   /someperlscript.pl ||
                [ "$((boff+=1))"  -ge "$lmt" ]
        do      [ -d "$ldir" ]     &&
                sleep "$boff"      || ! break
        done
;;esac  &&      _exec ldir PID

... বা এরকম কিছু। লুপের পিছনে থাকা মৌলিক যন্ত্রপাতিগুলি একবারে একবারে রিফ্রেশ করার অনুমতি দেয়।


1

আমি এই উত্তরগুলির কয়েকটি কয়েকটিকে উত্সাহিত করেছি, তবে @ ওয়াল্টারএর উত্তরের জন্য আমার সহজাত অনুভূতি রয়েছে। ঠিক আছে, আমি নিজের উত্তর তৈরি না করা পর্যন্ত করেছি ...

ব্যক্তিগতভাবে, আমি পার্ল স্ক্রিপ্টটি আপডেট করার প্রবণতা করব যাতে এটি ব্যর্থতা সম্পর্কে বর্ণনামূলক লগ এন্ট্রি লিখে এবং প্রশাসকের কাছে একটি সতর্কতা প্রেরণ করে।

যদি পার্ল স্ক্রিপ্টটি চালিয়ে যাওয়া বোঝানো হয়, ফাইল সিস্টেম থেকে ইভেন্টগুলি পরিবর্তনের জন্য অপেক্ষা করা হয় তবে এটি কেন ব্যর্থ হচ্ছে?

যদি এটি ব্যর্থ না হয়, তবে কেন এটি অনন্তর পুনরায় চালু করতে আপনি কোনও স্ক্রিপ্টে মুড়িয়ে ফেলার বিষয়ে উদ্বিগ্ন?

যদি কোনও কনফিগারেশন সমস্যা বা কিছু ভাঙা নির্ভরতা রয়েছে যার কারণে পার্ল স্ক্রিপ্টটি বাতিল হয়ে যায়, কেবল এটিকে পুনরায় আরম্ভ করার ফলে হঠাৎ এটি কাজ করা শুরু করে না।

আপনি পাগলের সংজ্ঞা জানেন, তাই না? (একই ফলাফল বারবার করছেন, ভিন্ন ফলাফলের আশা করছেন)। এমনি বলছি. ;-)


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

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