যদি কোনও প্রক্রিয়া মারা যায় তবে পুনরায় চালু করতে আমি কীভাবে বাশ স্ক্রিপ্ট লিখব?


226

আমার কাছে অজগর স্ক্রিপ্ট রয়েছে যা একটি সারি পরীক্ষা করে প্রতিটি আইটেমটিতে একটি ক্রিয়া সম্পাদন করবে:

# checkqueue.py
while True:
  check_queue()
  do_something()

আমি কীভাবে বাশ স্ক্রিপ্ট লিখব যা এটি চলমান কিনা তা খতিয়ে দেখবে, এবং যদি না হয় তবে এটি শুরু করুন। মোটামুটি নীচের সিউডো কোড (বা এটির মতো কিছু করা উচিত ps | grep?):

# keepalivescript.sh
if processidfile exists:
  if processid is running:
     exit, all ok

run checkqueue.py
write processid to processidfile

আমি একটি ক্রন্টব থেকে কল করব:

# crontab
*/5 * * * * /path/to/keepalivescript.sh

4
কেবল এটি 2017 এর জন্য যুক্ত করুন superv সুপারভাইজার ব্যবহার করুন। crontab এর অর্থ এই ধরণের কাজ করা নয়। আসল ত্রুটি নির্গত করার জন্য একটি বাশ স্ক্রিপ্ট ভয়ানক। stackoverflow.com/questions/9301494/...
mootmoot

অন্যান্য নন-সিস্টেমের সমাধানের পরিবর্তে ইনিটাব এবং রেসপন ব্যবহার সম্পর্কে কীভাবে? দেখুন superuser.com/a/507835/116705
লার্স নর্ডিন

উত্তর:


635

পিআইডি-ফাইল, ক্রোন বা অন্য কোনও কিছু এড়িয়ে চলুন যা তাদের বাচ্চাদের নয় এমন প্রক্রিয়াগুলি মূল্যায়নের চেষ্টা করে।

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

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

until myserver; do
    echo "Server 'myserver' crashed with exit code $?.  Respawning.." >&2
    sleep 1
done

উপরের অংশে বাশ কোডটি myserverএকটি untilলুপে চলে lo প্রথম লাইনটি শুরু হয় myserverএবং এটি শেষ হওয়ার জন্য অপেক্ষা করে। এটি শেষ হয়ে গেলে untilএর প্রস্থান স্থিতি পরীক্ষা করে। যদি প্রস্থান স্থিতি হয় 0তবে এর অর্থ এটি নিখুঁতভাবে শেষ হয়েছে (যার অর্থ আপনি এটি কোনওভাবে বন্ধ করতে বলেছেন, এবং এটি এত সফলভাবে করেছে)। সেক্ষেত্রে আমরা এটিকে পুনরায় চালু করতে চাই না (আমরা কেবল এটি বন্ধ করতে বলেছি!)। প্রস্থান অবস্থা হয়, তাহলে না 0 , untilলুপ শরীর, যা stderr উপর একটি ত্রুটির বার্তা নির্গত এবং লুপ (লাইন 1 ফিরে) রিস্টার্ট চালানো হবে 1 সেকেন্ড পর

আমরা কেন এক সেকেন্ড অপেক্ষা করব? কারণ যদি কোনও প্রারম্ভিক ক্রমটির সাথে কিছু ভুল হয়ে যায় myserverএবং তা অবিলম্বে ক্র্যাশ হয়ে যায়, আপনার হাতে ধ্রুবক পুনরায় চালু এবং ক্রাশ হওয়ার খুব নিবিড় লুপ থাকবে। sleep 1যে থেকে স্ট্রেন দূরে লাগে।

এখন আপনাকে যা করতে হবে তা হ'ল এই বাশ স্ক্রিপ্টটি শুরু করা (অবিচ্ছিন্নভাবে সম্ভবত, সম্ভবত), এবং এটি এটি পর্যবেক্ষণ করে myserverএবং প্রয়োজনীয় হিসাবে এটি পুনরায় আরম্ভ করবে। আপনি যদি বুটে মনিটরটি চালু করতে চান (সার্ভারটিকে "বেঁচে থাকা" রিবুটগুলি তৈরি করে), আপনি একটি @rebootনিয়ম সহ এটি আপনার ব্যবহারকারীর ক্রোন (1) এ শিডিউল করতে পারেন । এতে আপনার ক্রোন বিধিগুলি খুলুন crontab:

crontab -e

তারপরে আপনার মনিটরের স্ক্রিপ্ট শুরু করতে একটি বিধি যুক্ত করুন:

@reboot /usr/local/bin/myservermonitor

বিকল্পভাবে; inittab (5) এবং / ইত্যাদি / inittab দেখুন। myserverনির্দিষ্ট প্রাথমিক স্তরে শুরু করতে আপনি স্বয়ংক্রিয়ভাবে পুনঃস্থাপন করতে সেখানে একটি লাইন যুক্ত করতে পারেন ।


সম্পাদনা করুন।

পিআইডি ফাইলগুলি কেন ব্যবহার করবেন না সে সম্পর্কে আমাকে কিছু তথ্য যুক্ত করুন । যদিও তারা খুব জনপ্রিয়; এগুলিও খুব ত্রুটিযুক্ত এবং কোনও কারণ নেই যে আপনি কেবল এটি সঠিক উপায়ে করবেন না।

এই বিবেচনা:

  1. পিআইডি পুনর্ব্যবহারযোগ্য (ভুল প্রক্রিয়াটি হত্যা করা):

    • /etc/init.d/foo start: শুরু করুন foo, fooএর পিআইডি লিখুন/var/run/foo.pid
    • কিছুক্ষণ পরে: fooএকরকম মারা যায়।
    • কিছুক্ষণ পরে: যে কোনও র্যান্ডম প্রক্রিয়া শুরু হয় (এটি কল করুন bar) একটি এলোমেলো পিআইডি নেয়, এটি fooপুরানো পিআইডি গ্রহণ করার কথা কল্পনা করুন ।
    • আপনি লক্ষ্য fooকরেছেন যে: /etc/init.d/foo/restartপড়েছে /var/run/foo.pid, এটি এখনও জীবিত আছে কিনা তা পরীক্ষা করে দেখুন, এটি আবিষ্কার করেছেন bar, মনে করেন foo, হত্যা করে, একটি নতুন শুরু করে foo
  2. পিআইডি ফাইলগুলি বাসি হয়ে যায়। আপনার পিআইডি ফাইলটি বাসি কিনা তা পরীক্ষা করার জন্য আপনার অতিরিক্ত জটিল (বা আমি বলতে চাই, তুচ্ছ-তাত্পর্যপূর্ণ) যুক্তি প্রয়োজন, এবং এই জাতীয় কোনও যুক্তি আবারও ঝুঁকির মধ্যে রয়েছে 1.

  3. আপনি যদি লেখার অ্যাক্সেস না পেয়ে থাকেন বা কেবল পঠন-পরিবেশে থাকেন তবে কি হবে?

  4. এটি অর্থহীন অতিরিক্ত জটিলতা; উপরের আমার উদাহরণটি কত সহজ। একেবারেই জটিল করার দরকার নেই।

আরও দেখুন: পিআইডি-ফাইলগুলি 'ডান' করার সময় কি ত্রুটিযুক্ত?

যাইহোক; এর চেয়েও খারাপ পিআইডি ফাইলগুলি পার্সিং করছে ps! কখনও এই কাজ করবেন না।

  1. psখুব unportable। আপনি এটি প্রায় প্রতিটি ইউএনআইএক্স সিস্টেমে খুঁজে পেয়েছেন; যদি আপনি অ-মানক আউটপুট চান তবে এর আর্গুমেন্টগুলি ব্যাপকভাবে পরিবর্তিত হয়। এবং স্ট্যান্ডার্ড আউটপুট কেবলমাত্র মানুষের ব্যবহারের জন্য, স্ক্রিপ্টযুক্ত পার্সিংয়ের জন্য নয়!
  2. পার্সিং অনেকগুলি psমিথ্যা ধনাত্মক দিকে নিয়ে যায়। ps aux | grep PIDউদাহরণটি ধরুন , এবং এখন কল্পনা করুন যে কোনও ব্যক্তি কোথাও একটি সংখ্যা দিয়ে যুক্তি হিসাবে একটি প্রক্রিয়া শুরু করছেন যা আপনি আপনার ডিমনকে পিআইডি দিয়ে তাকাতে সমান হয়েছিলেন! দু'জন লোক এক্স সেশন শুরু করার কথা ভাবুন এবং আপনি এক্সকে মেরে ফেলার চেষ্টা করছেন। এটা সব ধরণের খারাপ।

আপনি যদি প্রক্রিয়াটি নিজে পরিচালনা করতে না চান; কিছু পুরোপুরি ভাল সিস্টেম আছে যা আপনার প্রক্রিয়াগুলির জন্য মনিটর হিসাবে কাজ করবে। উদাহরণস্বরূপ রুনিটের দিকে নজর দিন ।


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

2
@orschiro যখন প্রোগ্রামটি আচরণ করে তখন কোনও সংস্থান খরচ হয় না। এটি অবিলম্বে চালু হওয়ার পরে, অবিচ্ছিন্নভাবে, 1 ঘুমের সাথে রিসোর্স খরচ এখনও একেবারেই তুচ্ছ।
lhunath

7
বিশ্বাস করতে পারি আমি কেবল এই উত্তরটি দেখছি। অনেক ধন্যবাদ!
getWeberForStackExchange

2
@ টম্যাজাটো আপনি প্রক্রিয়াটির প্রস্থান কোড পরীক্ষা না করে উপরের লুপটি করতে পারেন while true; do myprocess; doneতবে নোট করুন যে প্রক্রিয়াটি থামানোর এখন আর কোনও উপায় নেই।
লুুনাথ

2
@ সের্গেপি.কাএজুরে বাশ-প্রস্থান করতে গিয়ে পিতামাতাকে মেরে ফেলার একমাত্র উপায় হ'ল শিশুটিকে একটি চাকরিতে পরিণত করা এবং এটির সংকেত দেওয়া:trap 'kill $(jobs -p)' EXIT; until myserver & wait; do sleep 1; done
লুুনাথ

33

Monit ( http://mmonit.com/monit/ ) এ দেখুন। এটি আপনার স্ক্রিপ্টটি শুরু, থামানো এবং পুনরায় চালু করতে পরিচালনা করে এবং প্রয়োজনে স্বাস্থ্য পরীক্ষা এবং প্লাস পুনরায় আরম্ভ করতে পারে।

অথবা একটি সাধারণ স্ক্রিপ্ট করুন:

while true
do
/your/script
sleep 1
done

4
মনিট ঠিক আপনি যা খুঁজছেন তা হ'ল।
সার্কে

4
"যখন 1" কাজ করে না। আপনার "যখন [1]" বা "সত্যের" বা "যখন:" দরকার। Unix.stackexchange.com/questions/367108/hat-does- moment
কার্টিস ইয়ালাপ

8

এটি করার সবচেয়ে সহজ উপায় হ'ল ফ্লক অন ফাইল ব্যবহার করা। পাইথন স্ক্রিপ্টে আপনি করতেন

lf = open('/tmp/script.lock','w')
if(fcntl.flock(lf, fcntl.LOCK_EX|fcntl.LOCK_NB) != 0): 
   sys.exit('other instance already running')
lf.write('%d\n'%os.getpid())
lf.flush()

শেলটিতে আপনি এটি চালাচ্ছেন কিনা তা পরীক্ষা করতে পারবেন:

if [ `flock -xn /tmp/script.lock -c 'echo 1'` ]; then 
   echo 'it's not running'
   restart.
else
   echo -n 'it's already running with PID '
   cat /tmp/script.lock
fi

তবে অবশ্যই আপনাকে পরীক্ষা করতে হবে না, কারণ এটি ইতিমধ্যে চলমান থাকলে এবং আপনি এটি পুনরায় চালু করলে এটি দিয়ে বেরিয়ে আসবে 'other instance already running'

প্রক্রিয়াটি মারা গেলে, সমস্ত ফাইল বর্ণনাকারী বন্ধ হয়ে যায় এবং সমস্ত লক স্বয়ংক্রিয়ভাবে সরানো হয়।


যা বাশ স্ক্রিপ্টটি সরিয়ে এটিকে কিছুটা সহজ করে তুলতে পারে। অজগর লিপি ক্রাশ হলে কী হবে? ফাইলটি কি আনলক করা আছে?
টম

1
হত্যা বন্ধ করে, প্রাকৃতিকভাবে বা ক্রাশ করে অ্যাপ্লিকেশনটি থামার সাথে সাথেই ফাইল লক প্রকাশিত হয়।
খ্রিস্টান উইটস

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

1
ব্যবহারের আরও অনেক ভাল উপায় আছে flock... প্রকৃতপক্ষে, ম্যান পৃষ্ঠাটি কীভাবে স্পষ্টভাবে প্রদর্শন করে! exec {lock_fd}>/tmp/script.lock; flock -x "$lock_fd"হ'ল বাশ হ'ল আপনার পাইথনের সমতুল্য, এবং লকটি রাখা আছে (সুতরাং আপনি যদি কোনও প্রক্রিয়া সম্পাদন করেন তবে সেই প্রক্রিয়াটি শেষ না হওয়া অবধি লকটি রাখা থাকবে)।
চার্লস ডাফি

আপনার কোডটি ভুল হওয়ায় আমি আপনাকে নিম্নমান এনেছি। ব্যবহার flockকরা সঠিক উপায় তবে আপনার স্ক্রিপ্টগুলি ভুল। flock -n /tmp/script.lock -c '/path/to/my/script.py'
ক্রোনট্যাব-এ

6

আপনার মনিত ব্যবহার করা উচিত, একটি মানক ইউনিক্স সরঞ্জাম যা সিস্টেমে বিভিন্ন জিনিস নিরীক্ষণ করতে পারে এবং সেই অনুযায়ী প্রতিক্রিয়া জানাতে পারে।

দস্তাবেজগুলি থেকে: http://mmonit.com/monit/docamentation/monit.html#pid_testing

পিডফিল /var/run/checkqueue.pid সহ চেক প্রসেস চেকইউ.পি
       যদি পিড পরিবর্তন হয় তবে "চেকিউইউ_স্টার্ট.শ" এক্সিকিউট করুন

মনিট আপনাকে ইমেল করতে কনফিগার করতে পারে যখন এটি পুনঃসূচনা করে।


2
মনিট একটি দুর্দান্ত সরঞ্জাম, তবে এটি পসিক্স বা এসএসভিতে কোনও একটিতে নির্দিষ্ট হওয়ার আনুষ্ঠানিক অর্থে মানক নয়
চার্লস ডাফি

5
if ! test -f $PIDFILE || ! psgrep `cat $PIDFILE`; then
    restart_process
    # Write PIDFILE
    echo $! >$PIDFILE
fi

দুর্দান্ত, এটি আমার সিউডো কোডটি বেশ ভালভাবে ফুটিয়ে তুলছে। দুটি qns: 1) আমি পিআইডিএফআইএল কিভাবে তৈরি করব? 2) psgrep কি? এটি উবুন্টু সার্ভারে নেই।
টম

পিএস গ্রেপ কেবল একটি ছোট অ্যাপ্লিকেশন যা একই রকম করে ps ax|grep ...। আপনি কেবল এটি ইনস্টল করতে পারেন বা এর জন্য একটি ফাংশন লিখতে পারেন: ফাংশন psgrep () ax ax PS ax | গ্রেপ-ভি গ্রেপ |
গ্রেপ -কিউ

সবেমাত্র লক্ষ্য করা গেছে যে আমি আপনার প্রথম প্রশ্নের উত্তর দিইনি।
আত্মবিগ্ন

7
সত্যই ব্যস্ত সার্ভারে আপনার চেক করার আগে পিআইডি পুনর্ব্যবহারযোগ্য হওয়া সম্ভব।
ভের্টেক

2

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

ম্যান পৃষ্ঠা থেকে:

এক-ক্রমাগত কম্যান্ড [আরজিএস]

দ্রষ্টব্য: স্পষ্টতই এটি আপনার স্ক্রিপ্টের মধ্যে থেকে কল করা যেতে পারে তবে এটি কোনও স্ক্রিপ্ট থাকার প্রয়োজনটিকেও সরিয়ে দেয়।


এটি কি গৃহীত উত্তরের চেয়ে কোনও সুবিধা দেয়?
ট্রিপলি

1
হ্যাঁ, আমি মনে করি একটি শেল স্ক্রিপ্ট লেখার চেয়ে একটি বিল্ট-ইন কমান্ড ব্যবহার করা ভাল, যা সিস্টেম কোডবেজের অংশ হিসাবে বজায় রাখতে হবে একই কাজ করে। এমনকি শেল স্ক্রিপ্টের অংশ হিসাবে যদি কার্যকারিতা প্রয়োজন হয় তবে উপরের কমান্ডটিও ব্যবহার করা যেতে পারে তাই এটি শেল স্ক্রিপ্টিং প্রশ্নের সাথে প্রাসঙ্গিক।
ড্যানিয়েল ব্র্যাডলি

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

দেখে মনে হচ্ছে এটি একটি উবুন্টু ইউটিলিটি; তবে এটি উবুন্টুতেও .চ্ছিক। manpages.ubuntu.com/manpages/bionic/man1/run-one.1.html
ট্রিপল

লক্ষ্যণীয়: রান-ওয়ান ইউটিলিটিগুলি তাদের নাম ঠিক তেমনটি করে - আপনি কেবল রান-ওয়ান-এনএনএনএন দিয়ে চালানো কোনও কমান্ডের একটি উদাহরণ চালাতে পারেন। এখানে অন্যান্য উত্তরগুলি আরও কার্যকরযোগ্য অগ্নিস্টিক - এটি কমান্ডের বিষয়বস্তুটির মোটেই পরোয়া করে না।
ডেভিড কোহেন

1

আমি অসংখ্য সার্ভারে দুর্দান্ত সাফল্যের সাথে নিম্নলিখিত স্ক্রিপ্টটি ব্যবহার করেছি:

pid=`jps -v | grep $INSTALLATION | awk '{print $1}'`
echo $INSTALLATION found at PID $pid 
while [ -e /proc/$pid ]; do sleep 0.1; done

মন্তব্য:

  • এটি জাভা প্রক্রিয়াটির সন্ধান করছে, তাই আমি জেপিএস ব্যবহার করতে পারি, এটি পিএসের চেয়ে বিতরণে অনেক বেশি সুসংগত
  • $INSTALLATION প্রক্রিয়াটির যথেষ্ট পরিমাণ রয়েছে যা এটি সম্পূর্ণ দ্ব্যর্থহীন
  • প্রক্রিয়াটি মারা যাওয়ার অপেক্ষায় ঘুম ব্যবহার করুন, হোগিং রিসোর্সগুলি এড়িয়ে চলুন :)

এই স্ক্রিপ্টটি টমক্যাটটির চলমান উদাহরণটি বন্ধ করতে ব্যবহৃত হয়, যা আমি কমান্ড লাইনে বন্ধ করতে (এবং অপেক্ষা করতে) চাই, তাই এটি শিশু প্রক্রিয়া হিসাবে চালু করা আমার পক্ষে সহজ নয়।


1
grep | awkএখনও একটি অ্যান্টিপ্যাটার্ন - আপনি অযৌক্তিক স্ক্রিপ্টে অকেজোকেawk "/$INSTALLATION/ { print \$1 }" সংযুক্ত করতে চান grep, যা নিয়মিত প্রকাশের মাধ্যমে খুব ভালভাবে লাইনগুলি খুঁজে পেতে পারে, আপনাকে অনেক ধন্যবাদ।
ট্রিপলি

0

আমি আমার এনপিএম প্রক্রিয়াটির জন্য এটি ব্যবহার করি

#!/bin/bash
for (( ; ; ))
do
date +"%T"
echo Start Process
cd /toFolder
sudo process
date +"%T"
echo Crash
sleep 1
done
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.