सवाल मैन्युअल रूप से और तत्काल एक क्रॉन नौकरी चलाना


(मैंने पहले ही पढ़ा है मैं एक नई क्रॉन स्क्रिप्ट का परीक्षण कैसे कर सकता हूं?।)

मेरे पास एक विशिष्ट समस्या है (क्रॉन जॉब चलाने के लिए प्रतीत नहीं होता है, या ठीक से चलाया जाता है), लेकिन समस्या सामान्य है: मैं क्रोन किए गए स्क्रिप्ट को डीबग करना चाहता हूं। मुझे पता है कि मैं * * * * * क्रोंटैब लाइन स्थापित कर सकता हूं, लेकिन यह पूरी तरह से संतोषजनक समाधान नहीं है। मैं कमांड लाइन से क्रॉन नौकरी चलाने में सक्षम होना चाहूंगा जैसे कि क्रॉन इसे चला रहा था (उसी उपयोगकर्ता, एक ही पर्यावरण चर, इत्यादि)। क्या इसे करने का कोई तरीका है? स्क्रिप्ट परिवर्तनों का परीक्षण करने के लिए 60 सेकंड प्रतीक्षा करने के लिए व्यावहारिक नहीं है।


94
2017-11-18 13:55


मूल


(क्षमा करें टिप्पणी नहीं जोड़ सकते हैं) 0 30 16 20 *? * यहां तक ​​कि यदि आप इस तरह की नौकरी चलाते हैं, तो पूरा विचार यह देखने के लिए स्क्रिप्ट आउटपुट प्रदान करना है कि जब तक जॉब लॉग पर लिखता है, तो यह गलत हो रहा है, यह बेकार है


जवाब:


यहां मैंने जो किया है, और ऐसा लगता है कि यह इस स्थिति में काम करता है। कम से कम, यह मुझे एक त्रुटि दिखाता है, जबकि कमांड लाइन से चल रहा है क्योंकि उपयोगकर्ता त्रुटि नहीं दिखाता है।


चरण 1: मैंने इस लाइन को अस्थायी रूप से उपयोगकर्ता के क्रॉन्टाब में रखा है:

* * * * *   /usr/bin/env > /home/username/tmp/cron-env

फ़ाइल लिखने के बाद इसे बाहर निकाला।

चरण 2: खुद को थोड़ा रन-ए-क्रॉन बैश स्क्रिप्ट बनाया गया है जिसमें:

#!/bin/bash
/usr/bin/env -i $(cat /home/username/tmp/cron-env) "$@"

तो फिर, उपयोगकर्ता के सवाल के रूप में, मैं करने में सक्षम था

run-as-cron /the/problematic/script --with arguments --and parameters

इस समाधान को सूडो या ऐसे लचीलेपन के लिए उपयोग करने के लिए स्पष्ट रूप से विस्तारित किया जा सकता है।

उम्मीद है कि यह दूसरों की मदद करता है।


73
2017-11-18 14:40



यह मेरे लिए काम नहीं करता है और मुझे आश्चर्य है कि यह किसी के लिए है जो ऊपर उठाया गया है। 1) आप बैश का उपयोग क्यों कर रहे हैं? यहां इसकी आवश्यकता नहीं है और यह इसमें स्थित नहीं हो सकता है /usr/bin। 2) द cat …/cron-env कई लाइनों का उत्पादन करता है, जो काम नहीं करता है। बस निष्पादित करने का प्रयास करें /usr/bin/env -i $(cat cron-env) echo $PATH टर्मिनल में, यह इसका उपयोग करने के बजाय सचमुच पर्यावरण को आउटपुट करता है। 3) वर्तमान वातावरण नकली cron पर्यावरण में लीक। प्रयत्न: export foo=leaked; run-as-cron echo $foo। - Marco
@ मार्को वर्क्स में बैश, जो मैं इसका उपयोग करता हूं वह श की तुलना में बेहतर परिभाषित वातावरण है। मैं पीडीकेश, केश (एकाधिक संस्करण), बैश और डैश से सबकुछ का उपयोग करता हूं, इसलिए मैं भाषाओं के सामान्य उप-समूह में बहुत सख्ती से रहने पर भी, "शुद्ध" के कार्यान्वयन के बीच अंतरों से अवगत हूं। :-) - Max Murphy
@ मार्को 2। cat कई लाइनों को आउटपुट करता है, जो काम करते हैं, क्योंकि खोल प्रतिस्थापन उन्हें एक ही पंक्ति में ढहता है, जिसे आप जांच सकते हैं echo $(cat cron-env ) | wc; आपका उदाहरण कमांड, /usr/bin/env -i $(cat cron-env) echo $PATHविकल्प $PATH कॉलिंग खोल से; इसके बजाय, इसे उपनिवेश में विकल्प के लिए एक सबहेल का आह्वान करना चाहिए, उदा। /usr/bin/env -i $(cat cron-env) /bin/sh -c 'echo $PATH'। 3. आपने एक ही गलती की है, फिर से उपनिवेश में बजाय कॉलिंग खोल में प्रतिस्थापित कर रहा है - John Freeman


मैं पिस्टोस के उत्तर के आधार पर एक समाधान प्रस्तुत करता हूं, लेकिन त्रुटियों के बिना।

  • निम्न पंक्ति को crontab में जोड़ें, उदा। का उपयोग करते हुए crontab -e

    * * * * *  /usr/bin/env > /home/username/cron-env
    
  • एक शेल स्क्रिप्ट बनाएं जो क्रॉन जॉब्स चलाने के समान वातावरण में कमांड निष्पादित करे:

    #!/bin/sh
    
    . "$1"
    exec /usr/bin/env -i "$SHELL" -c ". $1; $2"
    

उपयोग:

run-as-cron <cron-environment> <command>

जैसे

run-as-cron /home/username/cron-env 'echo $PATH'

ध्यान दें कि अगर किसी तर्क की आवश्यकता होती है तो दूसरे तर्क को उद्धृत करने की आवश्यकता होती है। स्क्रिप्ट की पहली पंक्ति एक पॉज़िक्स खोल को दुभाषिया के रूप में लोड करती है। दूसरी पंक्ति cron पर्यावरण फ़ाइल स्रोत। यह सही खोल लोड करने के लिए आवश्यक है, जो पर्यावरण चर में संग्रहीत है SHELL। फिर यह एक खाली वातावरण लोड करता है (नए खोल में पर्यावरण चर के लीक को रोकने के लिए), उसी शेल को लॉन्च करता है जिसका उपयोग cronjobs के लिए किया जाता है और क्रॉन पर्यावरण चर को लोड करता है। अंत में आदेश निष्पादित किया जाता है।


34
2017-09-24 18:46



इससे मुझे मेरी रूबी से संबंधित स्फिंक्स लोडिंग त्रुटि को पुन: उत्पन्न करने में मदद मिली। - cweiske
मैंने cron-env फ़ाइल लिखने के लिए @reboot cron विकल्प का उपयोग किया। इसके बाद आप इसे क्रोंटैब में छोड़ सकते हैं और सिस्टम को शुरू होने पर ही इसे फिर से लिखा जाएगा। यह थोड़ा आसान बनाता है क्योंकि आपको लाइनों को जोड़ने / हटाने की ज़रूरत नहीं है। - Michael Barton


चूंकि क्रॉन्टाब नौकरी नहीं करते हैं, तो आप इसकी सामग्री में हेरफेर करेंगे:

crontab -l | grep -v '^#' | cut -f 6- -d ' ' | while read CMD; do eval $CMD; done

यह क्या करता है :

  • crontab नौकरियों की सूची
  • टिप्पणी लाइनों को हटा दें
  • crontab विन्यास को हटा दें
  • फिर उन्हें एक-एक करके लॉन्च करें

14
2017-08-19 19:45



यह जरूरी नहीं है कि उसी वातावरण में क्रॉन होगा, और मैंने सोचा कि वह केवल उनमें से एक का परीक्षण करना चाहता था। - Falcon Momot
सही, मुझे गलती हो गई है ... यह केवल नौकरियां चलाती है लेकिन क्रॉन की तरह नहीं! - Django Janny
अभी भी एक भयानक समाधान +1 - Eric Uldall


डिफ़ॉल्ट रूप से मैंने देखा है कि अधिकांश डिफ़ॉल्ट क्रॉन डिमन्स के साथ, अभी यहां क्रॉन को चलाने के लिए कहने का कोई तरीका नहीं है। यदि आप एनाक्रोन का उपयोग कर रहे हैं, तो संभव है कि मैं अग्रभूमि में एक अलग उदाहरण चलाने के लिए सोचूं।

यदि आपकी स्क्रिप्ट ठीक से नहीं चल रही हैं तो आप उस पर ध्यान नहीं दे रहे हैं

  • स्क्रिप्ट एक विशेष उपयोगकर्ता के रूप में चल रहा है
  • क्रॉन में एक प्रतिबंधित वातावरण है (इसका सबसे स्पष्ट अभिव्यक्ति एक अलग पथ है)।

क्रोंटैब से (5):

कई पर्यावरण चर सेट हैं   क्रॉन द्वारा स्वचालित रूप से ऊपर (8)   डेमॉन। शेल / bin / sh पर सेट है, और   LOGNAME और HOME से सेट हैं   / etc / crontab की passwd लाइन   मालिक। पथ "/ usr / bin: / bin" पर सेट है।   घर, शेल, और पथ हो सकता है   में सेटिंग्स द्वारा ओवरराइड   crontab; LOGNAME उपयोगकर्ता है कि   नौकरी से चल रहा है, और हो सकता है   बदला हुआ।

आम तौर पर पीएटीएच सबसे बड़ी समस्या है, इसलिए आपको यह करना होगा:

  • स्पष्ट रूप से स्क्रिप्ट के भीतर पाथ सेट करें, परीक्षण करते समय, / usr / bin: / bin। आप इसे बाश में कर सकते हैं निर्यात PATH = "/ usr / bin: / bin"
  • स्पष्ट रूप से क्रॉन्टाब के शीर्ष पर इच्छित उचित पथ सेट करें। जैसे पथ = "/ usr / bin: / बिन: / usr / स्थानीय / बिन: / usr / sbin: / sbin"

यदि आपको स्क्रिप्ट के बिना किसी अन्य उपयोगकर्ता के रूप में स्क्रिप्ट चलाने की आवश्यकता है (उदा। Www-data), सुडो का उपयोग करें:

sudo -u www-data /path/to/crontab-script.sh

बेशक, इससे पहले परीक्षण करने वाली पहली बात यह है कि आपकी स्क्रिप्ट वास्तव में कमांड लाइन से क्या करना है। यदि आप इसे कमांड लाइन से नहीं चला सकते हैं, तो यह स्पष्ट रूप से क्रॉन से काम नहीं करेगा।


5
2017-11-18 14:27



पूरी प्रतिक्रिया के लिए धन्यवाद। मैं किसी विशेष उपयोगकर्ता के रूप में चलने के दो मुद्दों और एक विशेष वातावरण के बारे में जानता हूं। इस प्रकार, मैंने अपना खुद का जवाब तैयार किया है, जिसे मैं अब पोस्ट करूंगा ... - Pistos
बचने वाले अक्षर नौकरी के लिए चलने के वैध कारण हैं - Joe Phillips


खैर, उपयोगकर्ता क्रॉन्टाब एंट्री (या जिसका क्रॉन्टाब आप इसे वैकल्पिक रूप से डालता है) में डालता है, इसलिए यह कोई ब्रेनर नहीं है। crontab(5) आपको पर्यावरण चर सेट की सूची देनी चाहिए, केवल कुछ ही हैं।


1
2017-11-18 14:04



दूसरे शब्दों में, आप कह रहे हैं कि ऐसा करने का कोई तरीका नहीं है? केवल "पर्याप्त बंद करें" कामकाज? - Pistos
नहीं, मैं कह रहा हूं कि आप मेरे उत्तर में दी गई जानकारी का उपयोग करके इसे कर सकते हैं। - womble♦


उदाहरण के लिए अधिकांश crontabs में vixie-cron आप इस तरह crontab में चर डाल सकते हैं और फिर यह काम करने के लिए / usr / bin / env का उपयोग करें। रन-ए-क्रॉन स्क्रिप्ट के साथ क्या गलत है, इस तरह आप अपनी स्क्रिप्ट को क्रॉन्टाब में काम कर सकते हैं।

SHELL=/bin/bash
LANG=en
FASEL=BLA

* * * * *   /usr/bin/env > /home/username/cron-env

1
2017-10-27 06:52





कुछ कारणों से मार्को की लिपि मेरे लिए काम नहीं करती थी। मेरे पास डीबग करने का समय नहीं था, इसलिए मैंने एक पायथन लिपि लिखी जो एक ही काम करता है। यह लंबा है, लेकिन: सबसे पहले, यह मेरे लिए काम करता है, और दूसरा, मुझे समझना आसान लगता है। जहां आपने अपना पर्यावरण सहेजा था वहां "/ tmp / cron-env" बदलें। यह रहा:

#!/usr/bin/env python
from __future__ import division, print_function

import sys
import os

def main():
    if len(sys.argv) != 2 or sys.argv[1] in ('-h', '--help'):
        print("Usage: {} CMD\n"
              "Run a command as cron would. Note that CMD must be quoted to be only one argument."
              .format(sys.argv[0]))
        sys.exit(1)
    _me, cmd = sys.argv
    env = dict(line.strip().split('=', 1) for line in open('/tmp/cron-env'))
    sh = env['SHELL']
    os.execvpe(sh, [sh, '-c', cmd], env)

if __name__ == '__main__':
    main()

1
2017-12-24 08:48





मार्को का समाधान मेरे लिए काम नहीं करता था लेकिन नोएम की पायथन लिपि काम करती थी। यहां मार्को की लिपि में मामूली संशोधन है जिसने इसे मेरे लिए काम किया है:

#!/bin/sh
. "$1"
exec /usr/bin/env -i "$SHELL" -c "set -a;. $1; $2"

जोड़ा गया set -a स्क्रिप्ट $ 1 में परिभाषित निर्यात चर और इसे $ 2 कमांड के लिए उपलब्ध कराया गया

अनुलेख नोएम की अजगर काम करती है क्योंकि यह बाल प्रक्रिया में 'निर्यात' पर्यावरण है।


1
2018-05-11 05:05





मुझे मैन्युअल रूप से क्रॉन नौकरियों को चलाने का कोई तरीका नहीं मिला है इस लिखने का सुझाव उसी माहौल को स्थापित करने का सुझाव देता है जैसे cronjob होगा और स्क्रिप्ट को मैन्युअल रूप से चलाएगा।


0
2017-11-18 14:07



क्या आप ऐसा करने का सुझाव नहीं देते जो ओपी जानना चाहता है कि कैसे करना है? - womble♦
यही कारण है कि मैंने लेखन-पत्र के लिंक को शामिल किया जो वर्णन करता है कि इसे कैसे किया जाए। मैंने यह नहीं सोचा था कि यहां सब कुछ कॉपी-पेस्ट करना आवश्यक है। - oneodd1