প্রতি 15 সেকেন্ডে চালানোর জন্য কীভাবে একটি ইউনিক্স স্ক্রিপ্ট পাবেন?


84

আমি কয়েকটি সমাধান দেখেছি, সহ ঘড়ি এবং পটভূমিতে একটি লুপিং (এবং ঘুমন্ত) স্ক্রিপ্টটি চালানো সহ, তবে কিছুই আদর্শ হয়নি been

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

ইউনিক্সে প্রতি 15 সেকেন্ডে একটি স্ক্রিপ্ট চালানোর সবচেয়ে শক্তিশালী এবং দক্ষ উপায় কোনটি? স্ক্রিপ্টটি পুনরায় বুটের পরে চালানো দরকার।


4
এটি চালাতে কতক্ষণ সময় লাগে?
আদম মাতান

উত্তর:


77

আমি প্রতি মিনিটে স্ক্রিপ্ট চালানোর জন্য ক্রোন ব্যবহার করব এবং সেই স্ক্রিপ্টটি আপনার স্ক্রিপ্টটি রানের মধ্যে 15 সেকেন্ডের ঘুমের সাথে চারবার চালিত করে তুলবে।

(এটি ধরে নিয়েছে যে আপনার স্ক্রিপ্টটি দ্রুত চালানো হয়েছে - আপনি ঘুমের সময়গুলি সামঞ্জস্য করতে পারলে না))

এইভাবে, আপনি cronআপনার 15 দ্বিতীয় রান সময়কালের পাশাপাশি সমস্ত সুবিধা পাবেন ।

সম্পাদনা করুন: নীচে @ বিএমবি'র মন্তব্যও দেখুন।


@ আইডেন: হা! আমার নেমেসিস, আমরা আবার দেখা!
রিচিহিন্ডল

56
স্ক্রিপ্টটি চলতে কতক্ষণ সময় লাগে না তার সাথে সামঞ্জস্য না করলে স্ক্রিপ্টের চারটি অনুলিপি তৈরি করুন। একজন শুরু করার আগে 15 সেকেন্ড ঘুমায়, অন্য 30, অন্য 45, এবং অন্য শূন্য। তারপরে প্রতি মিনিটে চারটি চালান।
বিএমবি

@ রিচিহিন্দল - কোনও ভয় নেই, কয়েক সেকেন্ডের মধ্যে দানা না দেওয়ার জন্য আমি খুন হয়েছি। তবে আমি আপনাকে দেখছি: পি
আইডেন বেল

এই ক্রোন কীভাবে প্রতি 1 মিনিটে ট্রিগার করা যায়
DevZer0

আসলে আউটটার-স্ক্রিপ্টটি চারটি নয়, তিন বার অভ্যন্তরীণ স্ক্রিপ্টটি চালানো উচিত। অন্যথায় শেষ মিনিটের শেষ রানটি পরের মিনিটের ফ্রাইস্ট রানকে ওভারল্যাপ করবে। এটি প্রতি মিনিটে চারটির পরিবর্তে 5 বার অভ্যন্তরীণ স্ক্রিপ্টটি চালাবে।
তুলিনাস কর্ডোভা

292

আপনি যদি ক্রোন থেকে আপনার স্ক্রিপ্টটি চালানোর জন্য জিদ করেন:

* * * * * /foo/bar/your_script
* * * * * sleep 15; /foo/bar/your_script
* * * * * sleep 30; /foo/bar/your_script
* * * * * sleep 45; /foo/bar/your_script

এবং আপনার স্ক্রিপ্টের নাম এবং / foo / বার / আপনার_স্ক্রিপ্টের পথটি প্রতিস্থাপন করুন


4
এটি আমার জন্য পুরোপুরি কাজ করেন। ব্যাকগ্রাউন্ড টাস্কটি ব্যবহার করার উপরের এই সমাধানটি বেশ কয়েকটি শিশু প্রক্রিয়া তৈরি করেছিল এবং আমার শেষের দিকে মেমরির সমস্যার সৃষ্টি করে।
হ্যাকনিটলি

4
যদি পিএইচপি স্ক্রিপ্টটি চালায় তবে এটি করুন:* * * * * sleep 15; php /foo/bar/your_script
কল্পনাযুক্ত

4
যদি পিএইচপি স্ক্রিপ্ট চলমান থাকে তবে আপনি #!/usr/bin/phpআপনার পিএইচপি স্ক্রিপ্টের শীর্ষে লাইনটি
প্রিপেন্ড

18
আমি বিব্রত বোধ করি যে এই সমাধানের জন্য আমাকে গুগল করতে হয়েছিল। হয়তো স্ট্যাকওভারফ্লো আমাকে কম ভাবায়।
ক্রিস ফিন

@ হ্যাক নাইটলির প্রতিক্রিয়া হিসাবে, স্ক্রিপ্টগুলি যখন 15 সেকেন্ডের রানটাইম ছাড়িয়ে যায় এবং / বা কার্যগুলি সিস্টেমের দ্বারা ব্যবহৃত হতে পারে এমন যথেষ্ট মেমরি প্রকাশ করতে সক্ষম হয় না
অ্যাবেল ক্লেলেজো

15

উপরের পরিবর্তিত সংস্করণ:

mkdir /etc/cron.15sec
mkdir /etc/cron.minute
mkdir /etc/cron.5minute

/ etc / crontab এ যুক্ত করুন:

* * * * * root run-parts /etc/cron.15sec > /dev/null 2> /dev/null
* * * * * root sleep 15; run-parts /etc/cron.15sec > /dev/null 2> /dev/null
* * * * * root sleep 30; run-parts /etc/cron.15sec > /dev/null 2> /dev/null
* * * * * root sleep 45; run-parts /etc/cron.15sec > /dev/null 2> /dev/null

* * * * * root run-parts /etc/cron.minute > /dev/null 2> /dev/null
*/5 * * * * root run-parts /etc/cron.5minute > /dev/null 2> /dev/null

13

ব্যাকগ্রাউন্ডে এটি চালাবেন না?

#!/bin/sh
while [ 1 ]; do
    echo "Hell yeah!" &
    sleep 15
done

এটি যতটা দক্ষ তা প্রায় হিসাবে কার্যকর। গুরুত্বপূর্ণ অংশটি প্রতি 15 সেকেন্ডে কেবল কার্যকর হয় এবং স্ক্রিপ্টটি বাকি সময়টি ঘুমায় (এভাবে চক্র নষ্ট না করে)।


8
সম্পাদনাগুলি কমপক্ষে 8 টি অক্ষর হতে হবে (যা মূর্খ, আইএমএইচও) তাই আমি &লাইন 3 এর শেষে যুক্ত করতে পারিনি any যে কোনও ক্ষেত্রে, যেমন, এটি প্রতি 15 সেকেন্ডে চলবে না। এটি প্রতি "15 সেকেন্ডে চালায় + তবে echo helloচালাতে বেশি সময় নেয়"। যা 0.01 সেকেন্ড হতে পারে; 19 ঘন্টা হতে পারে।
পার্থিয়ান শট

1

আমি ক্রেনের চেয়ে দ্রুত একটি শিডিউল লিখেছিলাম wrote আমি একটি ওভারল্যাপিং প্রহরীও প্রয়োগ করেছি। পূর্ববর্তীটি এখনও চলমান থাকলে আপনি নতুন প্রক্রিয়া শুরু না করার জন্য সময়সূচীটি কনফিগার করতে পারেন। কটাক্ষপাত https://github.com/sioux1977/scheduler/wiki


0

ন্যানোস্লিপ (2) ব্যবহার করুন । এটি timespecএমন কাঠামো ব্যবহার করে যা ন্যানোসেকেন্ড যথার্থতার সাথে সময়ের ব্যবধানগুলি নির্দিষ্ট করতে ব্যবহৃত হয়।

struct timespec {
           time_t tv_sec;        /* seconds */
           long   tv_nsec;       /* nanoseconds */
       };

4
আমি এগিয়ে যাব এবং অনুমান করব যে তাদের ন্যানোসেকেন্ডের নির্ভুলতার প্রয়োজন নেই, যেহেতু তারা প্রতি 15 সেকেন্ডে যে জিনিসটি স্প্যান করছে তারা শেল স্ক্রিপ্ট, কার্নেল থ্রেড নয়।
পার্থিয়ান শট

@ পার্থিয়ানশট সম্ভবত আপনি কিন্তু জানেন না।
আলেকজান্ডার সুরাপেল

0
#! /bin/sh

# Run all programs in a directory in parallel
# Usage: run-parallel directory delay
# Copyright 2013 by Marc Perkel
# docs at http://wiki.junkemailfilter.com/index.php/How_to_run_a_Linux_script_every_few_seconds_under_cron"
# Free to use with attribution

if [ $# -eq 0 ]
then
   echo
   echo "run-parallel by Marc Perkel"
   echo
   echo "This program is used to run all programs in a directory in parallel" 
   echo "or to rerun them every X seconds for one minute."
   echo "Think of this program as cron with seconds resolution."
   echo
   echo "Usage: run-parallel [directory] [delay]"
   echo
   echo "Examples:"
   echo "   run-parallel /etc/cron.20sec 20"
   echo "   run-parallel 20"
   echo "   # Runs all executable files in /etc/cron.20sec every 20 seconds or 3 times a minute."
   echo 
   echo "If delay parameter is missing it runs everything once and exits."
   echo "If only delay is passed then the directory /etc/cron.[delay]sec is assumed."
   echo
   echo 'if "cronsec" is passed then it runs all of these delays 2 3 4 5 6 10 12 15 20 30'
   echo "resulting in 30 20 15 12 10 6 5 4 3 2 executions per minute." 
   echo
   exit
fi

# If "cronsec" is passed as a parameter then run all the delays in parallel

if [ $1 = cronsec ]
then
   $0 2 &
   $0 3 &
   $0 4 &
   $0 5 &
   $0 6 &
   $0 10 &
   $0 12 &
   $0 15 &
   $0 20 &
   $0 30 &
   exit
fi

# Set the directory to first prameter and delay to second parameter

dir=$1
delay=$2

# If only parameter is 2,3,4,5,6,10,12,15,20,30 then automatically calculate 
# the standard directory name /etc/cron.[delay]sec

if [[ "$1" =~ ^(2|3|4|5|6|10|12|15|20|30)$ ]]
then
   dir="/etc/cron.$1sec"
   delay=$1
fi

# Exit if directory doesn't exist or has no files

if [ ! "$(ls -A $dir/)" ]
then
   exit
fi

# Sleep if both $delay and $counter are set

if [ ! -z $delay ] && [ ! -z $counter ]
then
   sleep $delay
fi

# Set counter to 0 if not set

if [ -z $counter ]
then
   counter=0
fi

# Run all the programs in the directory in parallel
# Use of timeout ensures that the processes are killed if they run too long

for program in $dir/* ; do
   if [ -x $program ] 
   then
      if [ "0$delay" -gt 1 ] 
      then
         timeout $delay $program &> /dev/null &
      else
         $program &> /dev/null &
      fi
   fi
done

# If delay not set then we're done

if [ -z $delay ]
then
   exit
fi

# Add delay to counter

counter=$(( $counter + $delay ))

# If minute is not up - call self recursively

if [ $counter -lt 60 ]
then
   . $0 $dir $delay &
fi

# Otherwise we're done

0

আমার আগের উত্তরটি থেকে আমি আরও একটি সমাধান নিয়ে এসেছি যা আলাদা এবং সম্ভবত আরও ভাল। এই কোডটি মাইক্রোসেকেন্ড যথার্থতার সাথে এক মিনিটে 60 বারের বেশি প্রসেস চালানোর অনুমতি দেয়। এই কাজটি করতে আপনার ঘুমের প্রোগ্রাম দরকার। এক সেকেন্ডে 50 বার পর্যন্ত ভাল হওয়া উচিত।

#! /bin/sh

# Microsecond Cron
# Usage: cron-ms start
# Copyright 2014 by Marc Perkel
# docs at http://wiki.junkemailfilter.com/index.php/How_to_run_a_Linux_script_every_few_seconds_under_cron"
# Free to use with attribution

basedir=/etc/cron-ms

if [ $# -eq 0 ]
then
   echo
   echo "cron-ms by Marc Perkel"
   echo
   echo "This program is used to run all programs in a directory in parallel every X times per minute."
   echo "Think of this program as cron with microseconds resolution."
   echo
   echo "Usage: cron-ms start"
   echo
   echo "The scheduling is done by creating directories with the number of"
   echo "executions per minute as part of the directory name."
   echo
   echo "Examples:"
   echo "  /etc/cron-ms/7      # Executes everything in that directory  7 times a minute"
   echo "  /etc/cron-ms/30     # Executes everything in that directory 30 times a minute"
   echo "  /etc/cron-ms/600    # Executes everything in that directory 10 times a second"
   echo "  /etc/cron-ms/2400   # Executes everything in that directory 40 times a second"
   echo
   exit
fi

# If "start" is passed as a parameter then run all the loops in parallel
# The number of the directory is the number of executions per minute
# Since cron isn't accurate we need to start at top of next minute

if [ $1 = start ]
then
   for dir in $basedir/* ; do
      $0 ${dir##*/} 60000000 &
   done
   exit
fi

# Loops per minute and the next interval are passed on the command line with each loop

loops=$1
next_interval=$2

# Sleeps until a specific part of a minute with microsecond resolution. 60000000 is full minute

usleep $(( $next_interval - 10#$(date +%S%N) / 1000 ))

# Run all the programs in the directory in parallel

for program in $basedir/$loops/* ; do
   if [ -x $program ] 
   then
      $program &> /dev/null &
   fi
done

# Calculate next_interval

next_interval=$(($next_interval % 60000000 + (60000000 / $loops) ))

# If minute is not up - call self recursively

if [ $next_interval -lt $(( 60000000 / $loops * $loops)) ]
then
   . $0 $loops $next_interval &
fi

# Otherwise we're done

4
আবার পোস্ট করার পরিবর্তে আসলটি সম্পাদনা করুন!
ভোগন জেল্টজ

-1

মৃত্যুদন্ড কার্যকর করার সম্ভাব্য ওভারল্যাপিং এড়ানোর জন্য, সেই থ্রেডে বর্ণিত লকিং মেকানিজম ব্যবহার করুন ।


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