একটি দীর্ঘ ক্রোন কাজ সমান্তরালভাবে চালানো থেকে রোধ করার জেনেরিক সমাধান?


27

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

সম্পাদিত আদেশে সমাধানটি স্বাধীন হওয়া উচিত independent

আমি ধরে নিয়েছি এটি দেখতে এমন হওয়া উচিত lock && (command ; unlock)যেখানে অন্য কোনও লক থাকলে লকটি মিথ্যা ফিরে আসবে।

দ্বিতীয় অংশটি হ'ল যদি এটি ত্রুটি ফিরে আসে এমনকি যদি কমান্ড কার্যকর হওয়ার পরে লক, রান কমান্ড এবং আনলক অর্জন করে।

উত্তর:


33

কটাক্ষপাত রান একরান-ওয়ান ইনস্টল করুন প্যাকেজ। কমান্ডের ম্যানপেজrun-oneম্যানপেজ আইকন থেকে :

রান-ওয়ান একটি মোড়ক স্ক্রিপ্ট যা আর্গুমেন্টের একটি অনন্য সেট সহ কিছু কমান্ডের একের বেশি অনন্য ঘটনা চালায় না।

আপনি যখন একবারে একাধিক অনুলিপি না চান তখন এটি ক্রোনজবসগুলিতে প্রায়শই কার্যকর।

পছন্দ করুন timeবা sudo, আপনি কেবল এটি কমান্ডে প্রিপেন্ড করুন। সুতরাং একটি ক্রোনজব দেখতে দেখতে পারে:

  */60 * * * *   run-one rsync -azP $HOME example.com:/srv/backup

আরও তথ্য এবং পটভূমির জন্য, ব্লগ পোস্টটি ডাস্টিন কার্কল্যান্ডের সাথে পরিচয় করিয়ে দেখুন


5

একটি লক সেটআপ করার খুব সহজ উপায়:

if mkdir /var/lock/mylock; then
  echo "Locking succeeded" >&2
else
  echo "Lock failed - exit" >&2
  exit 1
fi

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

ব্যাশ লক সম্পর্কে আরও তথ্যের জন্য, এই পৃষ্ঠাটি দেখুন


1
আপনি একটি বহির্গমন ট্র্যাপও চাইবেন যা প্রস্থান করার সময় লকটি সরিয়ে ফেলবে। echo "Locking succeeded" >&2; trap 'rm -rf /var/lock/mylock' EXIT
গিরিহা

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

3

কিছু অভিনব প্যাকেজ ইনস্টল করার প্রয়োজন নেই:

#!/bin/bash
pgrep -xf "$*" > /dev/null || "$@"

"অ্যাপটি-ইনস্টল" চালানোর চেয়ে নিজে নিজে এই স্ক্রিপ্টটি লেখার পক্ষে দ্রুত, তাই না? আপনি কেবল বর্তমান ব্যবহারকারীর দ্বারা চালিত দৃষ্টান্তগুলি পরীক্ষা করতে পিজ্রিপ-এ "-u $ (id -u)" যুক্ত করতে চাইতে পারেন।


2
এটি একক উদাহরণের গ্যারান্টি দেয় না। দুটি স্ক্রিপ্ট ||একই সাথে অপারেটরের অন্য দিকে যেতে পারে , এর আগে দু'টিই স্ক্রিপ্টটি আরম্ভ করার সুযোগ পেয়েছে।
সেদাত কাপানোগলু

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

আমি এটি ব্যবহার করেছি তবে ব্যাশ স্ক্রিপ্টের জন্য যা নিজে যাচাই করা উচিত। কোডটি হ'ল: v = $ (pgrep -xf "/ bin / bash $ 0 $ @") ["$ {v / $ BASHPID /}"! = ""] & প্রস্থান 2
আহফম্যান

3

টিম কে এরও দেখুন solo, যা ব্যবহারকারীর কাছে অনন্য লুপব্যাক ঠিকানায় একটি পোর্টকে বাঁধাই করে লক সম্পাদন করে:

http://timkay.com/solo/

যদি তার সাইটটি নীচে যায়:

ব্যবহার:

solo -port=PORT COMMAND

where
    PORT        some arbitrary port number to be used for locking
    COMMAND     shell command to run

options
    -verbose    be verbose
    -silent     be silent

এটি এর মতো ব্যবহার করুন:

* * * * * solo -port=3801 ./job.pl blah blah

লিপি:

#!/usr/bin/perl -s
#
# solo v1.7
# Prevents multiple cron instances from running simultaneously.
#
# Copyright 2007-2016 Timothy Kay
# http://timkay.com/solo/
#
# It is free software; you can redistribute it and/or modify it under the terms of either:
#
# a) the GNU General Public License as published by the Free Software Foundation;
#    either version 1 (http://dev.perl.org/licenses/gpl1.html), or (at your option)
#    any later version (http://www.fsf.org/licenses/licenses.html#GNUGPL), or
#
# b) the "Artistic License" (http://dev.perl.org/licenses/artistic.html), or
#
# c) the MIT License (http://opensource.org/licenses/MIT)
#

use Socket;

alarm $timeout                              if $timeout;

$port =~ /^\d+$/ or $noport                     or die "Usage: $0 -port=PORT COMMAND\n";

if ($port)
{
    # To work with OpenBSD: change to
    # $addr = pack(CnC, 127, 0, 1);
    # but make sure to use different ports across different users.
    # (Thanks to  www.gotati.com .)
    $addr = pack(CnC, 127, $<, 1);
    print "solo: bind ", join(".", unpack(C4, $addr)), ":$port\n"   if $verbose;

    $^F = 10;           # unset close-on-exec

    socket(SOLO, PF_INET, SOCK_STREAM, getprotobyname('tcp'))       or die "socket: $!";
    bind(SOLO, sockaddr_in($port, $addr))               or $silent? exit: die "solo($port): $!\n";
}

sleep $sleep if $sleep;

exec @ARGV;

ম্যাক ওএসএক্সের জন্য, তৃতীয় প্যারামিটার পদ্ধতির জন্য solo(3801): Can't assign requested addressজোর না করা হলে এটি ত্রুটির সাথে ব্যর্থ হবে । BSD এর জন্য যা ভাল তা ম্যাকের পক্ষেও ভাল। 0pack
এরিক লেসচিনস্কি

1

আপনার একটি লক দরকার। run-oneকাজটি করে তবে আপনি প্যাকেজ flockথেকে সন্ধান করতেও পারেন util-linux

এটি কার্নেল বিকাশকারীদের দ্বারা সরবরাহিত একটি স্ট্যান্ডার্ড প্যাকেজ, এর চেয়ে আরও কাস্টমাইজেশনের অনুমতি দেয় run-oneএবং এটি এখনও খুব সহজ।


0

থেকে একটি সহজ সমাধান bash-hackers.org যে আমার জন্য কাজ ব্যবহার ছিল mkdir, । আপনার প্রোগ্রামের কেবলমাত্র একটি উদাহরণ চলছে কিনা তা নিশ্চিত করার জন্য এটি একটি সহজ উপায়। Mkdir। লক দিয়ে একটি ডিরেক্টরি তৈরি করুন যা ফিরে আসে

  • সত্য যদি সৃষ্টিটি সফল হয় এবং
  • লক ফাইলটি বিদ্যমান থাকলে মিথ্যা , বর্তমানে একটি উদাহরণ চলছে বলে ইঙ্গিত করে।

সুতরাং এই সাধারণ ফাংশনটি সমস্ত ফাইল লকিং যুক্তি করেছিল:

if mkdir .lock; then
    echo "Locking succeeded"
    eval startYourProgram.sh ;
else
    echo "Lock file exists. Program already running? Exit. "
    exit 1
fi


echo "Program finished, Removing lock."
rm -r .lock

0

এই সমাধানটি ব্যাশ স্ক্রিপ্টের জন্য যা নিজে নিজে যাচাই করা দরকার

v=$(pgrep -xf "/bin/bash $0 $@")
[ "${v/$BASHPID/}" != "" ] && exit 0
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.