ইতিমধ্যে চালু না থাকলে ক্রোন জব চালান


136

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

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

আমি এই পোস্টটি পেয়েছি , যা লক ফাইলগুলি ব্যবহার করে যা করার চেষ্টা করছি তার একটি সমাধান সরবরাহ করেছিল, এটির আরও ভাল উপায় আছে কিনা তা সম্পর্কে আমি নিশ্চিত নই ...

আপনার সাহায্যের জন্য ধন্যবাদ.

উত্তর:


120

আমি এটি প্রিন্ট স্পুলার প্রোগ্রামের জন্য করি যা আমি লিখেছিলাম, এটি কেবল একটি শেল স্ক্রিপ্ট:

#!/bin/sh
if ps -ef | grep -v grep | grep doctype.php ; then
        exit 0
else
        /home/user/bin/doctype.php >> /home/user/bin/spooler.log &
        #mailing program
        /home/user/bin/simplemail.php "Print spooler was not running...  Restarted." 
        exit 0
fi

এটি প্রতি দুই মিনিটে চলে এবং এটি বেশ কার্যকর। কোনও কারণে প্রক্রিয়াটি চলমান না থাকলে আমার কাছে এটি বিশেষ তথ্য সহ ইমেল করুন have


4
খুব নিরাপদ সমাধান নয়, তবে যদি আপনি গ্রেপ-তে অনুসন্ধানের সাথে মেলে এমন অন্যান্য প্রক্রিয়াও থাকে? আরএসএন্ডেনের উত্তর পিডফাইল ব্যবহার করে সেই ধরণের সমস্যাটিকে বাধা দেয়।
ইলিয়াস ডরনেলেস

12
এই চাকাটি ইতিমধ্যে অন্য কোথাও আবিষ্কার করা হয়েছিল :) উদাহরণস্বরূপ, সার্ভারসফল্ট
ফিলিপ

5
পরিবর্তে grep -v grep | grep doctype.phpআপনি করতে পারেন grep [d]octype.php
অ্যালেক্সটি

নোট করুন যে &এটির জন্য স্ক্রিপ্টটি ক্রোন চালানোর প্রয়োজন নেই ।
লাইনত্নবী

124

ব্যবহার flock । এটা নতুন. এটা আরও ভাল।

এখন আপনাকে নিজেরাই কোড লিখতে হবে না। আরও কারণ এখানে দেখুন: https://serverfault.com/a/82863

/usr/bin/flock -n /tmp/my.lockfile /usr/local/bin/my_script

1
একটি খুব সহজ সমাধান
এমএফবি

4
সেরা সমাধান, আমি এটি সত্যই দীর্ঘকাল ধরে ব্যবহার করছি।
soger

1
আমি এখানেও একটি সুন্দর ক্রোন টেম্পলেট গিস্ট তৈরি করেছি
জেস

3
setlock, s6-setlock, chpst, এবং runlockতাদের অ ব্লক মোড মধ্যে বিকল্প যে শুধু লিনাক্স চেয়ে বেশি পাওয়া যায় হয়। unix.stackexchange.com/a/475580/5132
JdeBP

3
আমি মনে করি এটি গ্রহণযোগ্য উত্তর হওয়া উচিত। খুবই সোজা!
কোডমনকি

62

অন্যরা যেমন বলেছে, পিআইডি ফাইল লেখা এবং চেক করা ভাল সমাধান। এখানে আমার বাশ বাস্তবায়ন:

#!/bin/bash

mkdir -p "$HOME/tmp"
PIDFILE="$HOME/tmp/myprogram.pid"

if [ -e "${PIDFILE}" ] && (ps -u $(whoami) -opid= |
                           grep -P "^\s*$(cat ${PIDFILE})$" &> /dev/null); then
  echo "Already running."
  exit 99
fi

/path/to/myprogram > $HOME/tmp/myprogram.log &

echo $! > "${PIDFILE}"
chmod 644 "${PIDFILE}"

3
+1 একটি পিডফিল ব্যবহার করে এটি সম্ভবত একই নামে চলমান প্রোগ্রামের জন্য গ্রেপিংয়ের চেয়ে অনেক বেশি নিরাপদ।
ইলিয়াস ডরনেলেস

/ পাথ / টু / মাইপোগ্রাম এবং> OME হোম / টিএমপি / মাইপোগ্রাম.লগ এবং ?????? করেনি আপনি সম্ভবত গড় / পথ / থেকে / myprogram >> $ হোম / tmp / 'myprogram.log &
Matteo

1
স্ক্রিপ্ট শেষ হয়ে গেলে ফাইলটি সরানো উচিত নয়? বা আমি খুব স্পষ্ট কিছু মিস করছি?
হামজাহফ্রাক

1
@ মাত্তিও: হ্যাঁ, আপনি ঠিক বলেছেন। আমি কয়েক বছর আগে আমার নোটগুলিতে এটি স্থির করেছিলাম তবে এটি এখানে আপডেট করতে ভুলে গেছি। সবচেয়ে খারাপ, আমি আপনার মন্তব্যেও এটি মিস করেছি, কেবল " >" বনাম " >>" লক্ষ্য করে। এর জন্যে দুঃখিত.
রন্ধন করুন

5
@ হামজাহফ্রিকিউ: এটি কীভাবে কাজ করে তা এখানে: স্ক্রিপ্টটি প্রথমে পিআইডি ফাইল উপস্থিত রয়েছে কিনা তা পরীক্ষা [ -e "${PIDFILE}" ]করে দেখায় (" " এটি যদি না থাকে, তবে এটি পটভূমিতে প্রোগ্রামটি শুরু করবে, তার পিআইডি কোনও ফাইলে (" echo $! > "${PIDFILE}"") লিখবে , এবং প্রস্থান করুন। যদি এর পরিবর্তে পিআইডি ফাইল উপস্থিত থাকে, তবে স্ক্রিপ্টটি আপনার নিজস্ব প্রক্রিয়াগুলি (" ps -u $(whoami) -opid=") পরীক্ষা করবে এবং দেখুন আপনি একই পিআইডি (" grep -P "^\s*$(cat ${PIDFILE})$"") দিয়ে একটি চালাচ্ছেন কিনা তা যদি আপনি না থাকেন তবে এটি শুরু হবে পূর্বের মত প্রোগ্রাম, নতুন পিআইডি দিয়ে পিআইডি ফাইলটি ওভাররাইট করে প্রস্থান করুন আমি স্ক্রিপ্টটি পরিবর্তন করার কোনও কারণ দেখতে পাচ্ছি না আপনি?
রন্ধন

35

অবাক করা বিষয় যে কেউ রান-ওয়ান সম্পর্কে উল্লেখ করেনি । আমি এই দিয়ে আমার সমস্যা সমাধান করেছি।

 apt-get install run-one

তারপরে run-oneআপনার ক্রন্টব স্ক্রিপ্টের আগে যুক্ত করুন

*/20 * * * * * run-one python /script/to/run/awesome.py

পরীক্ষা করে দেখুন এই askubuntu দঃপূঃ উত্তর। আপনি সেখানে একটি বিশদ তথ্যের লিঙ্কও খুঁজে পেতে পারেন।


22

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


5
ক্লাসিক উপায়টি হল একটি পিআইডি ফাইল পড়া যা পরিষেবাটি শুরু হওয়ার সাথে সাথে সার্ভিস তৈরি করে, সেই পিআইডি সহ প্রক্রিয়াটি এখনও চলছে কিনা তা পরীক্ষা করে দেখুন এবং না হলে পুনরায় চালু করুন।
tvanfosson

9

আপনি সরাসরি আপনার ক্রন্টবায় এটি ওয়ান-লাইনার হিসাবেও করতে পারেন:

* * * * * [ `ps -ef|grep -v grep|grep <command>` -eq 0 ] && <command>

5
খুব নিরাপদ নয়, যদি গ্রেপের সাথে অনুসন্ধানের সাথে মেলে এমন অন্যান্য কমান্ডও রয়েছে?
ইলিয়াস ডরনেলেস

1
এটি * * * * * [ ps -ef|grep [c]ommand-eq 0] && <command> হিসাবেও লেখা যেতে পারে যেখানে আপনার কমান্ডের প্রথম অক্ষরটি বন্ধনীতে মোড়ানো এটি গ্রেপ ফলাফল থেকে বাদ দেয়।
জিম ক্লাউজ

আমাকে নিম্নলিখিত বাক্য গঠন ব্যবহার করতে হয়েছিল: [ "$(ps -ef|grep [c]ommand|wc -l)" -eq 0 ] && <command>
থিমেরা

1
এটা ঘৃণ্য। [ $(grep something | wc -l) -eq 0 ]সত্যিই লেখার এক চক্রাকার উপায় ! grep -q something। সুতরাং আপনি সহজভাবে চানps -ef | grep '[c]ommand' || command
ট্রিপল

(এছাড়াও, যদি আপনি সত্যই ম্যাচিং লাইনের সংখ্যা গণনা করতে চান তবে একদিকে যেমন grep -c)।
ট্রিপলি

7

আমি পিএইচপি স্ক্রিপ্টগুলি চালানোর সময় আমি যেভাবে এটি করছি তা হ'ল:

ক্রোনটব:

* * * * * php /path/to/php/script.php &

পিএইচপি কোড:

<?php
if (shell_exec('ps aux | grep ' . __FILE__ . ' | wc  -l') > 1) {
    exit('already running...');
}
// do stuff

এই কমান্ডটি বর্তমান পিএইচপি ফাইলনামের জন্য সিস্টেম প্রক্রিয়া তালিকার সন্ধান করছে যদি এটি উপস্থিত থাকে তবে লাইন কাউন্টার (ডাব্লুসি-এল) এর চেয়ে বড় হবে কারণ অনুসন্ধান কমান্ড নিজেই ফাইলের নাম ধারণ করে

সুতরাং আপনি যদি পিএইচপি ক্রোনগুলি চালাচ্ছেন তবে আপনার পিএইচপি কোড শুরুতে উপরের কোডটি যুক্ত করুন এবং এটি কেবল একবারই চলবে।


ক্লায়েন্ট সার্ভারে এমন কিছু ইনস্টল করা দরকার যা অন্যান্য সমাধানগুলির জন্য আমার প্রয়োজন ছিল যা আমার কাছে অ্যাক্সেস নেই।
জেফ ডেভিস

5

আর্লজ উত্তরের অনুসরণ হিসাবে, আপনার একটি মোড়ক স্ক্রিপ্ট দরকার যা একটি $ PID.running ফাইল তৈরি হয় এবং এটি শেষ হয়ে গেলে মুছুন। মোড়ক স্ক্রিপ্ট আপনাকে যে স্ক্রিপ্টটি চালাতে চান তা কল করে। টার্গেট স্ক্রিপ্ট ব্যর্থ হলে বা ত্রুটিগুলি বের হয়ে যায়, তবে পিড ফাইলটি মুছে ফেলা হবে The


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


3

আমি কোনও বিদ্যমান সরঞ্জাম যেমন মনিট ব্যবহার করার পরামর্শ দেব , এটি নিরীক্ষণ করবে এবং স্বয়ংক্রিয় পুনঃসূচনা প্রক্রিয়া করবে। এখানে আরও তথ্য পাওয়া যায় । এটি বেশিরভাগ বিতরণে সহজেই পাওয়া উচিত।


এটি বাদে প্রতিটি উত্তর পৃষ্ঠতল প্রশ্নের উত্তর দেয় "আমার ক্রোন জব কীভাবে নিশ্চিত করতে পারে যে এটি কেবলমাত্র একটি উদাহরণ চালায়?" যখন আসল প্রশ্নটি হয় "আমি কীভাবে পুনরায় আরম্ভের মুখে আমার প্রক্রিয়াটি চালিয়ে রাখতে পারি?", এবং সঠিক উত্তরটি ক্রোন ব্যবহার না করা, বরং পরিবর্তে মনিটের মতো একটি প্রক্রিয়া তত্ত্বাবধায়ক। অন্যান্য অপশন অন্তর্ভুক্ত runit , S6 বা, যদি আপনার বন্টন ইতিমধ্যে systemd ব্যবহার করে, মাত্র প্রক্রিয়া কি systemd হল পরিষেবা তৈরি চাহিদা জীবিত রাখতে হবে যে।
ক্লেক

3

এইটা আমাকে কখনই ব্যর্থ করে না:

এক.শ :

LFILE=/tmp/one-`echo "$@" | md5sum | cut -d\  -f1`.pid
if [ -e ${LFILE} ] && kill -0 `cat ${LFILE}`; then
   exit
fi

trap "rm -f ${LFILE}; exit" INT TERM EXIT
echo $$ > ${LFILE}

$@

rm -f ${LFILE}

ক্রোন জব :

* * * * * /path/to/one.sh <command>

3
# one instance only (works unless your cmd has 'grep' in it)
ALREADY_RUNNING_EXIT_STATUS=0
bn=`basename $0`
proc=`ps -ef | grep -v grep | grep "$bn" | grep -v " $$ "`
[ $? -eq 0 ] && {
    pid=`echo $proc | awk '{print $2}'`
    echo "$bn already running with pid $pid"
    exit $ALREADY_RUNNING_EXIT_STATUS
}

হালনাগাদ .. পশুর ব্যবহারের আরও ভাল উপায়:

/usr/bin/flock -n /tmp/your-app.lock /path/your-app args 

1

আমি রস্যান্ডেনের উত্তরের উন্নতি হিসাবে নিম্নলিখিতটি প্রস্তাব করব (আমি একটি মন্তব্য হিসাবে পোস্ট করব, তবে পর্যাপ্ত খ্যাতি নেই ...):

#!/usr/bin/env bash

PIDFILE="$HOME/tmp/myprogram.pid"

if [ -e "${PIDFILE}" ] && (ps -p $(cat ${PIDFILE}) > /dev/null); then
  echo "Already running."
  exit 99
fi

/path/to/myprogram

এটি সম্ভাব্য মিথ্যা ম্যাচগুলি এড়িয়ে যায় (এবং গ্রেপিংয়ের ওভারহেড), এবং এটি আউটপুটকে দমন করে এবং কেবলমাত্র PS এর প্রস্থান স্থিতির উপর নির্ভর করে।


1
আপনার psকমান্ডটি কেবল নিজের নয়, অন্য ব্যবহারকারীদের জন্য পিআইডি মিলবে match কমান্ডটিতে একটি " -u" যুক্ত করা psপ্রস্থান স্থিতিটি কাজ করার পদ্ধতি পরিবর্তন করে।
রন্ধন করুন

1

সাধারণ কাস্টম পিএইচপি অর্জনের জন্য যথেষ্ট। শেল স্ক্রিপ্টের সাথে বিভ্রান্ত করার দরকার নেই।

ধরে নিই আপনি চলমান না হলে php / home/mypath/example.php চালাতে চান

তারপরে একই কাজটি করতে নিম্নলিখিত কাস্টম পিএইচপি স্ক্রিপ্ট ব্যবহার করুন।

নিম্নলিখিত / home/mypath/forever.php তৈরি করুন

<?php
    $cmd = $argv[1];
    $grep = "ps -ef | grep '".$cmd."'";
    exec($grep,$out);
    if(count($out)<5){
        $cmd .= ' > /dev/null 2>/dev/null &';
        exec($cmd,$out);
        print_r($out);
    }
?>

তারপরে আপনার ক্রোনটিতে নিম্নলিখিতগুলি যুক্ত করুন

* * * * * php /home/mypath/forever.php 'php /home/mypath/example.php'

0

আপনি যদি সেই রুটে যেতে যাচ্ছেন তবে গ্রেগের মাধ্যমে পিএস পাইপ করার পরিবর্তে পিগ্রিপ (যদি উপলব্ধ থাকে) ব্যবহার বিবেচনা করুন। যদিও, ব্যক্তিগতভাবে, আমি ফর্মের স্ক্রিপ্টগুলি থেকে অনেক মাইলেজ পেয়েছি

while(1){
  call script_that_must_run
  sleep 5
}

যদিও ব্যর্থ পারে এবং cron কাজ হয় প্রায়ই অপরিহার্য উপাদানের জন্য সবচেয়ে ভালো উপায়। অন্য একটি বিকল্প।


2
এটি বার বার ডেমোন শুরু করবে এবং উপরে উল্লিখিত সমস্যাটির সমাধান করবে না।
cwebker

0

দস্তাবেজ: https://www.timkay.com/solo/

একক একটি খুব সাধারণ স্ক্রিপ্ট (10 লাইন) যা কোনও প্রোগ্রামে একসাথে একাধিক অনুলিপি চালানো থেকে বিরত থাকে। আগের কাজ শেষ হওয়ার আগে কোনও কাজ চলবে না তা নিশ্চিত করার জন্য ক্রোন দিয়ে এটি দরকারী।

উদাহরণ

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