স্ক্রিপ্টটি ম্যানুয়ালি আহ্বানের পরিবর্তে ক্রোন দ্বারা শুরু হয়েছে কিনা তা পরীক্ষা করুন


23

কোনও প্রোগ্রাম চলাকালীন ক্রোন সেট করে এমন কোনও পরিবর্তনশীল আছে কি? স্ক্রিপ্টটি ক্রোন দ্বারা চালিত হলে, আমি কিছু অংশ ছেড়ে যেতে চাই; অন্যথায় এই অংশগুলি প্রার্থনা করুন।

বাশ স্ক্রিপ্টটি ক্রোন দিয়ে শুরু করা হয়েছে কিনা আমি কীভাবে জানতে পারি?


তুমি শুধু আমাদেরই psকরছ না কেন ?
terdon


@ ইটারডন: সম্ভবত কারণটি psমোটামুটিভাবে খারাপভাবে নথিভুক্ত হয়েছে (বিশেষত লিনাক্সের সংস্করণ যা বিভিন্ন সিন্ট্যাক্সের বিভিন্ন স্টাইল সমর্থন করে) এবং ম্যান পৃষ্ঠাটি বেশিরভাগ সরঞ্জামের চেয়ে আরও ঘন এবং ক্রিপ্টিক। আমার সন্দেহ হয় যে কোনও সরঞ্জাম কীভাবে দরকারী এবং বহুমুখী psহতে পারে তা বেশিরভাগ লোকেরা বুঝতেও পারেন না।
ক্যাস

উত্তর:


31

আমি সচেতন নই যে cronডিফল্টরূপে এর পরিবেশের জন্য এমন কিছু করে যা এখানে ব্যবহারযোগ্য হতে পারে তবে আপনি পছন্দসই প্রভাব পেতে বেশ কয়েকটি জিনিস করতে পারেন।

1) স্ক্রিপ্ট ফাইলটিতে একটি শক্ত বা নরম লিঙ্ক তৈরি করুন, উদাহরণস্বরূপ, myscriptএবং myscript_via_cronএকই ফাইলটিতে নির্দেশ করুন। আপনি $0যখন শর্তাধীন কোডের কিছু অংশ চালাতে বা বাদ দিতে চান তখন আপনি স্ক্রিপ্টের অভ্যন্তরের মানটি পরীক্ষা করতে পারেন। আপনার ক্রন্টাবে উপযুক্ত নাম রাখুন, এবং আপনি সেট হয়ে গেছেন।

2) স্ক্রিপ্টে একটি বিকল্প যুক্ত করুন, এবং ক্রোনটব অনুরোধে সেই বিকল্পটি সেট করুন। উদাহরণস্বরূপ, একটি বিকল্প যুক্ত করুন -c, যা স্ক্রিপ্টকে কোডের উপযুক্ত অংশগুলি চালনা বা বাদ দিতে বলে -cএবং আপনার ক্রন্টবায় কমান্ডের নাম যুক্ত করে।

এবং অবশ্যই, ক্রন করতে , নির্বিচারে বিভিন্ন পরিবেশের সেট যাতে আপনি ঠিক একটি লাইন করা হতে পারে RUN_BY_CRON="TRUE"আপনার নিম্নলিখিতরূপে crontab পরিবর্তন, এবং আপনার স্ক্রিপ্টের মধ্যে এর মান পরীক্ষা করুন।


7
RUN_BY_CRON জন্য +1 সত্য =
CA গুলির

ক্যাসের উত্তরটি খুব ভাল কাজ করছে এবং অন্য যে কোনও কিছুর জন্যও ব্যবহার করা যেতে পারে
দেিয়ান

19

ক্রোন থেকে চালিত স্ক্রিপ্টগুলি ইন্টারেক্টিভ শেলগুলিতে চালিত হয় না। না কোনও স্টার্টআপ স্ক্রিপ্ট। পার্থক্যটি হ'ল ইন্টারেক্টিভ শেলগুলিতে একটি টিটিটির সাথে STDIN এবং STDOUT যুক্ত থাকে।

পদ্ধতি 1: পতাকাটি $-অন্তর্ভুক্ত কিনা তা পরীক্ষা করুন iiইন্টারেক্টিভ শেল জন্য সেট করা হয়।

case "$-" in
    *i*)
        interactive=1
        ;;
    *)
        not_interactive=1
        ;;
esac

পদ্ধতি 2: চেক $PS1খালি আছে।

if [ -z "$PS1" ]; then
    not_interactive=1 
else
    interactive=1
fi

তথ্যসূত্র: http://techdoc.kvindesland.no/linux/gnubooks/bash/bashref_54.html

পদ্ধতি 3: আপনার tty পরীক্ষা করুন। এটা না হিসাবে নির্ভরযোগ্য, কিন্তু ক্রন একটি স্ক্রিপ্ট করার জন্য একটি TTY বরাদ্দ ডিফল্টরূপে না সহজ cron কাজ করার জন্য আপনাকে ঠিক হতে হবে।

if [ -t 0 ]; then
    interactive=1
else
    non_interactive=1
fi

মনে রাখবেন যে আপনি যদি কোনও ইন্টারেক্টিভ শেল ব্যবহার করে জোর করতে পারেন তবে -iআপনি সম্ভবত এটি সচেতন হন যদি আপনি এটি করছেন ...


1
নোট করুন যে স্ক্রিপ্টটি সিস্টেমড দ্বারা শুরু হয়েছে কিনা তা পরীক্ষা করার সময় $ PS1 কমান্ড কাজ করে না। দি one - একটি করে
mveroone

1
আপনার উইনিপেগ বিশ্ববিদ্যালয়ের লিঙ্কটি নষ্ট হয়ে গেছে।
WinEunuuchs2 ইউনিক্স

1
@ টিম কেনেডি আপনি স্বাগত .... এডমন্টন থেকে :)
উইনউনুচস

'কেস "$ -" ইন "ব্যাশ স্ক্রিপ্টগুলিতে কাজ করে না।
হোবাদি

@Hobadee - যে bashআমার আছে $ এক্সেস আছে -, হিসেবে dashএবং ksh। এমনকি সোলারিসের সীমাবদ্ধ শেলও এটিতে রয়েছে। কোন প্ল্যাটফর্মটি এটি কাজ করছে না সেখানে এটি ব্যবহার করার চেষ্টা করছেন? তোমাকে কী case "$-" in *i*) echo true ;; *) echo false ;; esacদেখায়?
টিম কেনেডি

7

প্রথমে ক্রোনের পিআইডি পান, তারপরে বর্তমান প্রক্রিয়ার প্যারেন্ট পিআইডি (পিপিআইডি) পান এবং তাদের তুলনা করুন:

CRONPID=$(ps ho %p -C cron)
PPID=$(ps ho %P -p $$)
if [ $CRONPID -eq $PPID ] ; then echo Cron is our parent. ; fi

যদি আপনার স্ক্রিপ্টটি ক্রোন দ্বারা শুরু করা অন্য কোনও প্রক্রিয়া দ্বারা শুরু করা হয়, তবে আপনি প্যারেন্ট পিআইডিগুলিকে ব্যাক আপ করতে পারেন যতক্ষণ না আপনি কোনও $ CRONPID বা 1 (init এর পিআইডি) না পান।

এর মতো কিছু হতে পারে, (অদ্বিতীয়-তবে-এটি-মাইট-ওয়ার্ক <টিএম>):

PPID=$$   # start from current PID
CRON_IS_PARENT=0
CRONPID=$(ps ho %p -C cron)
while [ $CRON_IS_PARENT -ne 1 ] && [ $PPID -ne 1 ] ; do
  PPID=$(ps ho %P -p $PPID)
  [ $CRONPID -eq $PPID ] && CRON_IS_PARENT=1
done

দেিয়ান থেকে: এটি রেডহ্যাট লিনাক্সে পরীক্ষিত একটি সংস্করণ

# start from current PID
MYPID=$$
CRON_IS_PARENT=0
# this might return a list of multiple PIDs
CRONPIDS=$(ps ho %p -C crond)

CPID=$MYPID
while [ $CRON_IS_PARENT -ne 1 ] && [ $CPID -ne 1 ] ; do
        CPID_STR=$(ps ho %P -p $CPID)
        # the ParentPID came up as a string with leading spaces
        # this will convert it to int
        CPID=$(($CPID_STR))
        # now loop the CRON PIDs and compare them with the CPID
        for CRONPID in $CRONPIDS ; do
                [ $CRONPID -eq $CPID ] && CRON_IS_PARENT=1
                # we could leave earlier but it's okay like that too
        done
done

# now do whatever you want with the information
if [ "$CRON_IS_PARENT" == "1" ]; then
        CRON_CALL="Y"
else
        CRON_CALL="N"
fi

echo "CRON Call: ${CRON_CALL}"

1
সোলারিস ক্রোন একটি শেল শুরু করে এবং শেলটি স্ক্রিপ্টটি চালায় যা নিজেই অন্য শেলটি শুরু করে। সুতরাং স্ক্রিপ্টের প্যারেন্ট পিড ক্রোনের পিড নয়।
17:

4

যদি আপনার স্ক্রিপ্ট ফাইলটি চালিত হয় cronএবং এটিতে প্রথম লাইনে একটি শেল থাকে যেমন #!/bin/bashআপনার প্রয়োজনের জন্য পিতামাতার নাম খুঁজে পাওয়া দরকার।

1) cronপ্রদত্ত crontabসময়টিতে আপনার শেল চালানো হয় 2) শেলটি আপনার স্ক্রিপ্টটি কার্যকর করে 3) আপনার স্ক্রিপ্ট চলছে

প্যারেন্ট পিআইডি ভেরিয়েবল হিসাবে ব্যাশে উপলব্ধ $PPIDpsকমান্ড পিতা বা মাতা PID, হয় পিতা বা মাতা PID, পেতে:

PPPID=`ps h -o ppid= $PPID`

তবে আমাদের কমান্ডের নাম দরকার, পিড নয়, তাই আমরা কল করি

P_COMMAND=`ps h -o %c $PPPID`

এখন আমাদের "ক্রোন" এর জন্য ফলাফলটি পরীক্ষা করা দরকার

if [ "$P_COMMAND" == "cron" ]; then
  RUNNING_FROM_CRON=1
fi

এখন আপনি আপনার স্ক্রিপ্টের যে কোনও জায়গায় পরীক্ষা করতে পারেন

if [ "$RUNNING_FROM_CRON" == "1" ]; then
  ## do something when running from cron
else
  ## do something when running from shell
fi

শুভকামনা!


এটি কেবল লিনাক্স PS এর জন্য কাজ করে। ম্যাকওএসের জন্য (পাশাপাশি লিনাক্স, * বিএসডিও সম্ভবত) আপনি নিম্নলিখিত P_COMMAND ব্যবহার করতে পারেন:P_COMMAND=$(basename -a $(ps h -o comm $PPPID))
এমডিডি

1

ফ্রিবিএসডি বা লিনাক্সে কাজ করে:

if [ "Z$(ps o comm="" -p $(ps o ppid="" -p $$))" == "Zcron" -o \
     "Z$(ps o comm="" -p $(ps o ppid="" -p $(ps o ppid="" -p $$)))" == "Zcron" ]
then
    echo "Called from cron"
else
    echo "Not called from cron"
fi

আপনি যতটা ইচ্ছা প্রসেস ট্রিটি উপরে যেতে পারেন can


1

"আমার আউটপুটটি একটি টার্মিনাল বা আমি কোনও স্ক্রিপ্ট থেকে চলছি" এই প্রশ্নের জেনেরিক সমাধানটি হ'ল:

( : > /dev/tty) && dev_tty_good=y || dev_tty_good=n

0

echo $TERM | mail me@domain.comক্রোন একটি সাধারণ আমাকে দেখিয়েছে যে লিনাক্স এবং এআইএক্স, উভয়ই ক্রোন $TERM'বোবা' হয়ে গেছে।

এখন তাত্ত্বিকভাবে এখনও চারপাশে সত্যিকারের বোবা টার্মিনাল থাকতে পারে, তবে আমি সন্দেহ করি যে বেশিরভাগ ক্ষেত্রে, এটি যথেষ্ট হওয়া উচিত ...


0

কোনও অনুমোদনমূলক উত্তর নেই, তবে প্রম্পট ( $PS1) এবং টার্মিনাল ( $TERM) ভেরিয়েবলগুলি এখানে বেশ শালীন। বেশিরভাগ সিস্টেমে সেট TERM=dumbহয়ে থাকে যখন বেশিরভাগ এটিকে খালি রেখে দেয়, তাই আমরা কেবল এটির জন্য পরীক্ষা করব:

if [ "${TERM:-dumb}$PS1" != "dumb" ]; then
  echo "This is not a cron job"
fi

উপরের কোডটি "বোবা" শব্দের প্রতিস্থাপন করে যখন এর কোনও মূল্য নেই $TERM। অতএব, শর্তাধীন দাবানল নেই যখন $TERMবা $TERM"বোবা" থেকে অথবা যদি সেট করা হয় $PS1পরিবর্তনশীল খালি না থাকে।

আমি এটি ডেবিয়ান 9 ( TERM=), সেন্টোস 6.4 এবং 7.4 ( TERM=dumb) এবং ফ্রিবিএসডি 7.3 ( TERM=) এ পরীক্ষা করেছি।

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