पर्यावरण क्रॉन का अनुकरण कैसे करें के साथ एक स्क्रिप्ट निष्पादित करता है?


253

मुझे आमतौर पर कई समस्याएं हैं कि क्रोन लिपियों को कैसे निष्पादित करते हैं क्योंकि उनके पास सामान्य रूप से मेरा पर्यावरण सेटअप नहीं है। क्या बैश (?) को लागू करने का एक तरीका है जिस तरह से क्रोन करता है इसलिए मैं उन्हें स्थापित करने से पहले स्क्रिप्ट का परीक्षण कर सकता हूं?


मैं इस समाधान का सुझाव दूंगा
रुडी

@Gregseth को थोड़ा और आगे बढ़ाते हुए, मैंने यह समाधान दिया: unix.stackexchange.com/questions/27289/…
रॉबर्ट ब्रिसिटा

जवाबों:


385

इसे अपने crontab (अस्थायी रूप से) में जोड़ें:

* * * * * env > ~/cronenv

इसके चलने के बाद, यह करें:

env - `cat ~/cronenv` /bin/sh

यह मानता है कि आपका क्रोन / बिन / श चलता है, जो उपयोगकर्ता के डिफ़ॉल्ट शेल की परवाह किए बिना डिफ़ॉल्ट है।


5
नोट: यदि इसे वैश्विक / etc / crontab में जोड़ा जाए, तो आपको उपयोगकर्ता नाम की भी आवश्यकता होगी। जैसे * * * * * जड़ env> ~ / cronenv
ग्रेग

10
अच्छा, सरल विचार। अगले मिनट चलाने के लिए अधीर उपयोग के लिए * * * * * *, और फिर से बंद करने के लिए याद रखें जब आप खेल रहे हैं ;-)
Madus Buus

5
@ मैडसन पिछले बैश शेल में लौटने के लिए प्रयास करें: बाहर निकलें
स्पॅकेन

5
इस उत्तर के महत्व को कम करके नहीं आंका जा सकता। एक पुस्तक में एक अनुच्छेद शामिल किए जाने के योग्य।
Xofo

1
क्या env - बिल्ली ~ / cronenv` / bin / sh` को क्रॉन जॉब भी लिखा जाना चाहिए? कृपया एक उदाहरण दें
JavaSa

61

क्रोन डिफ़ॉल्ट रूप से केवल यही वातावरण प्रदान करता है:

  • HOME उपयोगकर्ता के घर निर्देशिका
  • LOGNAME उपयोगकर्ता का लॉगिन
  • PATH=/usr/bin:/usr/sbin
  • SHELL=/usr/bin/sh

यदि आपको अधिक आवश्यकता है, तो आप एक स्क्रिप्ट का स्रोत बना सकते हैं, जहां आप अपने वातावरण को क्राउन में शेड्यूलिंग टेबल से पहले परिभाषित करते हैं।


7
.सुरक्षा कारणों सेPATH , आमतौर पर अब इसका हिस्सा नहीं है
l0b0

49

दृष्टिकोण के जोड़े:

  1. निर्यात cron env और इसे स्रोत:

    जोड़ना

    * * * * * env > ~/cronenv

    अपने कोट्रैब पर, इसे एक बार चलने दें, इसे वापस चालू करें, फिर चलाएं

    env - `cat ~/cronenv` /bin/sh

    और आप अब एक shसत्र के अंदर हैं जिसमें क्रोन का वातावरण है

  2. अपने पर्यावरण को क्रोन पर ले आओ

    आप व्यायाम से ऊपर जा सकते हैं और बस . ~/.profileअपनी क्रोन नौकरी के सामने कर सकते हैं, जैसे

    * * * * * . ~/.profile; your_command
  3. स्क्रीन का उपयोग करें

    दो समाधानों से ऊपर अभी भी इसमें विफल हैं कि वे एक चल रहे एक्स सत्र से जुड़े वातावरण प्रदान करते हैं, dbusउदाहरण के लिए, आदि के लिए, उबंटू पर, nmcli(नेटवर्क मैनेजर) दो दृष्टिकोणों से ऊपर काम करेगा, लेकिन फिर भी क्रॉन में विफल रहता है।

    * * * * * /usr/bin/screen -dm

    क्रोन के ऊपर की रेखा जोड़ें, इसे एक बार चलने दें, इसे वापस बंद करें। अपने स्क्रीन सत्र (स्क्रीन -r) से कनेक्ट करें। यदि आप स्क्रीन सेशन की जाँच कर रहे हैं (बनाया गया है ps) जानते हैं कि वे कभी-कभी राजधानियों में होते हैं (जैसे ps | grep SCREEN)

    अब भी nmcliऔर इसी तरह विफल हो जाएगा।


22

तुम दौड़ सकते हो:

env - your_command arguments

यह खाली वातावरण के साथ आपका_कमांड चलाएगा।


4
क्रोन पूरी तरह से खाली वातावरण में नहीं चलता है, यह करता है?
१२:१०

2
gregseth ने क्रोन द्वारा पर्यावरण में शामिल चर की पहचान की। आप कमांड लाइन पर उस चर को शामिल कर सकते हैं। $ env - PATH = "$ PATH" कमांड आर्गन्स
DragonFax

4
@DragonFax @dimba मैं env - HOME="$HOME" LOGNAME="$USER" PATH="/usr/bin:/bin" SHELL="$(which sh)" command argumentsजो चाल का उपयोग करने के लिए लगता है
l0b0

यह "शत्रुतापूर्ण" या अज्ञात वातावरण में स्क्रिप्ट का परीक्षण करने के लिए एक महान सरल विधि है। यदि आप पर्याप्त स्पष्ट हैं कि यह इसमें चलेगा, तो यह क्रोन के तहत चलेगा।
ओली


13

छह साल बाद जवाब देना: पर्यावरण बेमेल समस्या systemdएक क्रॉन प्रतिस्थापन के रूप में "टाइमर" द्वारा हल की गई समस्याओं में से एक है। चाहे आप सीएलआई से या क्रोन के माध्यम से सिस्टमड "सेवा" चलाते हैं, यह पर्यावरण बेमेल समस्या से बचने के साथ बिल्कुल वैसा ही वातावरण प्राप्त करता है।

क्रोन नौकरियों को विफल करने के लिए सबसे आम मुद्दा जब वे मैन्युअल रूप से पास होते हैं तो $PATHक्रोन द्वारा प्रतिबंधात्मक डिफ़ॉल्ट सेट होता है, जो कि 16.04 बजे इस पर होता है:

"/usr/bin:/bin"

इसके विपरीत, Ubuntu 16.04 पर डिफ़ॉल्ट $PATHसेट systemdहै:

"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

तो पहले से ही एक बेहतर मौका है कि एक सिस्टम टाइमर बिना किसी परेशानी के द्विआधारी खोजने जा रहा है।

सिस्टमसाइड टाइमर के साथ नकारात्मक पक्ष यह है कि उन्हें स्थापित करने के लिए थोड़ा और समय है। आप पहली बार "सेवा" फ़ाइल बनाते हैं जिसे आप चलाना चाहते हैं और इसे चलाने के लिए शेड्यूल को परिभाषित करने के लिए एक "टाइमर" फ़ाइल और अंत में इसे सक्रिय करने के लिए टाइमर को "सक्षम" करें।


10

एक क्रॉन जॉब बनाएं जो एनवी को चलाता है और एक फाइल पर stdout रीडायरेक्ट करता है। "Env -" के साथ फ़ाइल का उपयोग करें, क्रोन जॉब के समान वातावरण बनाने के लिए।


क्षमा करें यह मुझे उलझन में डाल दिया। "एनवी - स्क्रिप्ट" पर्याप्त नहीं है?
जॉर्ज वर्गास

जो आपको एक खाली वातावरण देगा। जब आप क्रोन के माध्यम से स्क्रिप्ट चलाते हैं, तो वातावरण खाली नहीं होता है।
जेन्स कार्लबर्ग

3

मत भूलो कि चूँकि क्रोन के माता-पिता के लिए यह एक नियंत्रण टर्मिनल के बिना कार्यक्रम चलाता है। आप इस तरह से एक उपकरण के साथ अनुकरण कर सकते हैं:

http://libslack.org/daemon/


2

डिफ़ॉल्ट रूप से, cronआपके सिस्टम के विचार का उपयोग करके अपनी नौकरियों को निष्पादित करता shहै। यह वास्तविक बॉर्न शैल हो सकता है या dash, ash, kshया bash(या एक और एक) के लिए सांकेतिक रूप से लिंक sh(और POSIX मोड में चल रहा एक परिणाम के रूप में)।

सबसे अच्छी बात यह है कि सुनिश्चित करें कि आपकी स्क्रिप्ट में वही है जो उन्हें चाहिए और उनके लिए कुछ भी उपलब्ध नहीं है। इसलिए, आपको पूर्ण निर्देशिका विनिर्देशों का उपयोग करना चाहिए और $PATHअपने जैसे पर्यावरण चर सेट करना चाहिए ।


यह वही है जो मैं हल करने की कोशिश कर रहा हूं। हमें लिपियों के साथ कई समस्याएं आती हैं जो गलती से कुछ मान लेते हैं। पूर्ण पथों को करना और env वेरिएबल्स को सेट करना और सभी कबाड़ भयानक विशाल अचूक क्रोन लाइनों के साथ समाप्त होते हैं
जॉर्ज वर्गास

पुनः * श खेद है कि मैं बैश = खोल के साथ बड़ा हुआ हूं इसलिए मेरे लिए विकल्प (और कभी-कभी बेहतर) गोले को याद रखना कठिन है।
जॉर्ज वर्गास

1
@ जॉर्ज: क्रॉस्टैब में लाइनें काफी कम होनी चाहिए। आपको स्क्रिप्ट (या एक आवरण स्क्रिप्ट) के भीतर आवश्यक सभी सेटअप करना चाहिए। यहाँ एक उदाहरण के रूप में एक क्रेस्टैब से एक विशिष्ट रेखा है: 0 0 * * 1 /path/to/executable >/dev/null 2>&1और फिर, "निष्पादन योग्य" के भीतर, मैं इसके लिए मान सेट करूँगा $PATH, आदि, और इनपुट और आउटपुट फ़ाइलों के लिए पूर्ण निर्देशिका चश्मा का उपयोग करें, उदाहरण के लिए:/path/to/do_something /another/path/input_file /another/path/to/output_file
आगे की सूचना तक रोका गया।

1

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

/Etc/cron.d/ स्क्रिप्ट का संपादन:

* * * * * user1 comand-that-needs-env-vars

में बदल जाएगा:

* * * * * user1 source ~/.bash_profile; source ~/.bashrc; comand-that-needs-env-vars

गंदा, लेकिन यह मेरे लिए काम कर गया। क्या एक लॉगिन अनुकरण करने का एक तरीका है? बस एक कमांड आप चला सकते हैं?bash --loginकाम नहीं किया। ऐसा लगता है कि हालांकि जाने के लिए बेहतर तरीका होगा।

संपादित करें: यह एक ठोस समाधान प्रतीत होता है: http://www.epicserve.com/blog/2012/feb/7/my-notes-cron-directory-etccrond-ubuntu-1110/

* * * * * root su --session-command="comand-that-needs-env-vars" user1 -l

1

स्वीकृत उत्तर पर्यावरण क्रोन के साथ एक स्क्रिप्ट को चलाने का एक तरीका देता है। जैसा कि अन्य ने बताया, क्रोन नौकरियों को डिबग करने के लिए यह एकमात्र आवश्यक मानदंड नहीं है।

वास्तव में, क्रोन एक गैर-संवादात्मक टर्मिनल का उपयोग करता है, बिना संलग्न इनपुट आदि के।

यदि यह मदद करता है, तो मैंने एक स्क्रिप्ट लिखी है जो दर्द रहित रूप से कमांड / स्क्रिप्ट चलाने में सक्षम है क्योंकि यह क्रोन द्वारा चलाया जाएगा। इसे अपने कमांड / स्क्रिप्ट के साथ पहले तर्क के रूप में लागू करें और आप अच्छे हैं।

यह स्क्रिप्ट भी जीथब पर होस्ट की गई है (और संभवतः अपडेट की गई है) ।

#!/bin/bash
# Run as if it was called from cron, that is to say:
#  * with a modified environment
#  * with a specific shell, which may or may not be bash
#  * without an attached input terminal
#  * in a non-interactive shell

function usage(){
    echo "$0 - Run a script or a command as it would be in a cron job, then display its output"
    echo "Usage:"
    echo "   $0 [command | script]"
}

if [ "$1" == "-h" -o "$1" == "--help" ]; then
    usage
    exit 0
fi

if [ $(whoami) != "root" ]; then
    echo "Only root is supported at the moment"
    exit 1
fi

# This file should contain the cron environment.
cron_env="/root/cron-env"
if [ ! -f "$cron_env" ]; then
    echo "Unable to find $cron_env"
    echo "To generate it, run \"/usr/bin/env > /root/cron-env\" as a cron job"
    exit 0
fi

# It will be a nightmare to expand "$@" inside a shell -c argument.
# Let's rather generate a string where we manually expand-and-quote the arguments
env_string="/usr/bin/env -i "
for envi in $(cat "$cron_env"); do
   env_string="${env_string} $envi "
done

cmd_string=""
for arg in "$@"; do
    cmd_string="${cmd_string} \"${arg}\" "
done

# Which shell should we use?
the_shell=$(grep -E "^SHELL=" /root/cron-env | sed 's/SHELL=//')
echo "Running with $the_shell the following command: $cmd_string"


# Let's route the output in a file
# and do not provide any input (so that the command is executed without an attached terminal)
so=$(mktemp "/tmp/fakecron.out.XXXX")
se=$(mktemp "/tmp/fakecron.err.XXXX")
"$the_shell" -c "$env_string $cmd_string" >"$so" 2>"$se" < /dev/null

echo -e "Done. Here is \033[1mstdout\033[0m:"
cat "$so"
echo -e "Done. Here is \033[1mstderr\033[0m:"
cat "$se"
rm "$so" "$se"

0

उत्तर https://stackoverflow.com/a/2546509/5593430 से पता चलता है कि क्रोन वातावरण कैसे प्राप्त करें और इसे अपनी स्क्रिप्ट के लिए उपयोग करें। लेकिन इस बात से अवगत रहें कि आपके द्वारा उपयोग किए जाने वाले क्रेस्टैब फाइल के आधार पर वातावरण अलग-अलग हो सकता है। मैंने पर्यावरण को बचाने के लिए तीन अलग-अलग क्रोन प्रविष्टियां बनाईं env > log। ये अमेज़न लिनक्स 4.4.35-33.55.amzn1.x86_64 पर परिणाम हैं।

1. रूट यूजर के साथ ग्लोबल / आदि / क्रॉस्टैब

MAILTO=root
SHELL=/bin/bash
USER=root
PATH=/sbin:/bin:/usr/sbin:/usr/bin
PWD=/
LANG=en_US.UTF-8
SHLVL=1
HOME=/
LOGNAME=root
_=/bin/env

2. रूट का उपयोगकर्ता crontab ( crontab -e)

SHELL=/bin/sh
USER=root
PATH=/usr/bin:/bin
PWD=/root
LANG=en_US.UTF-8
SHLVL=1
HOME=/root
LOGNAME=root
_=/usr/bin/env

3. स्क्रिप्ट /etc/cron.hourly/ में

MAILTO=root
SHELL=/bin/bash
USER=root
PATH=/sbin:/bin:/usr/sbin:/usr/bin
_=/bin/env
PWD=/
LANG=en_US.UTF-8
SHLVL=3
HOME=/
LOGNAME=root

सबसे महत्वपूर्ण बात PATH, PWDऔर HOMEअलग। स्थिर वातावरण पर भरोसा करने के लिए अपनी क्रोन स्क्रिप्ट में इन्हें सेट करना सुनिश्चित करें।


-8

मुझे विश्वास नहीं है कि वहाँ है; एकमात्र तरीका मैं जानता हूं कि क्रॉन जॉब का परीक्षण करना भविष्य में एक या दो मिनट चलाने के लिए इसे सेट करना है और फिर इंतजार करना है।


यही कारण है कि मैं अनुकरण पूछ रहा हूं
जॉर्ज वर्गास
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.