প্রতি মাসের শেষ দিনটি নির্ধারণ করুন


10

আমি মাসের শেষ দিনে একটি স্ক্রিপ্ট শিডিউল করার জন্য একটি নির্দেশনা থেকে পড়েছি:

দ্রষ্টব্য: চমত্কার
পাঠক হয়ত ভাবছেন যে আপনি কীভাবে প্রতি মাসের শেষ দিনে কার্যকর করার জন্য একটি আদেশ সেট করতে সক্ষম হবেন কারণ আপনি প্রতি মাসের জন্য ডেথমোথ মান নির্ধারণ করতে পারবেন না। এই সমস্যাটি লিনাক্স এবং ইউনিক্স প্রোগ্রামারদের জর্জরিত করেছে এবং বেশ কয়েকটি পৃথক সমাধান তৈরি করেছে। একটি সাধারণ পদ্ধতি হ'ল যদি একটি বিবৃতি যুক্ত করা হয় যা ডেট কমান্ড ব্যবহার করে আগামীকাল তারিখটি 01 হয় কিনা তা পরীক্ষা করে দেখুন:

00 12 * * * if [`date +%d -d tomorrow` = 01 ] ; then ; command1

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

এখানে চিত্র বর্ণনা লিখুন

কিভাবে [`date +%d -d tomorrow` = 01 ]কাজ করে?
এটা কি সঠিক then; command1?


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

আমি স্ন্যাপশট পোস্ট করেছি। @ মাইকেলহোমর
ক্যালকুলাস

ধন্যবাদ! আমি এটির সাথে মিলিয়ে ফরম্যাটিং দিয়ে বেঁধেছি - এটি এখনও ঠিক সঠিক নয়, তবে চিত্রটি যা বলে তা তাই।
মাইকেল হোমার

1
মিস করছি ; endif?
danblack

এটি কাজ করে না। এটিতে সিনট্যাক্স ত্রুটি রয়েছে: শেষে কোনও স্থান [নেই fiএবং শেষ নেই। এছাড়াও, %crontabs বিশেষ।
কুসালানন্দ

উত্তর:


17

বিমূর্ত

সঠিক কোডটি হওয়া উচিত:

#!/bin/sh
[ "$#" -eq 0 ] && echo "Usage: $0 command [args]" && exit 1
[ "$(date -d tomorrow +'%d')" = 01 ] || exit 0
exec "$@"

এই স্ক্রিপ্টটি end_of_month.shকল করুন এবং ক্রનમાં কলটি কেবলমাত্র:

00 12 28-31 * * /path/to/script/end_of_month.sh command

এটি স্ক্রিপ্টটি চালিত করবে end_of_month(যা অভ্যন্তরীণভাবে পরীক্ষা করবে যে দিনটি মাসের শেষ দিন) কেবল ২৮, ২৯, ৩০, ৩১ এবং ৩১ দিনে। অন্য কোনও দিন মাসের শেষের জন্য পরীক্ষা করার দরকার নেই।

পুরানো পোস্ট।

এটি রিচার্ড ব্লাম, ক্রিস্টিন ব্রেসনাহান পিপি 442, তৃতীয় সংস্করণ, জন উইলে অ্যান্ড সন্স © 2015 এর "লিনাক্স কমান্ড লাইন এবং শেল স্ক্রিপ্টিং বাইবেল" বইয়ের একটি উদ্ধৃতি।

হ্যাঁ, এটি যা বলে তা কিন্তু এটি ভুল / অসম্পূর্ণ:

  • একটি ক্লোজিং মিস করছি fi
  • [নিম্নলিখিত এবং এর মধ্যে স্থানের প্রয়োজন `
  • এটা তোলে হয় জোরালোভাবে $ (...) পরিবর্তে ব্যবহার করা বাঞ্ছনীয় `…`
  • এটা খুবই গুরুত্বপূর্ণ যে আপনার চারপাশের কোট ব্যবহার প্রসারণও মত"$(…)"
  • ;পরে একটি অতিরিক্ত আছেthen

আমি কিভাবে জানবো? (ভাল, অভিজ্ঞতা দ্বারা ☺) তবে আপনি শেলচেক চেষ্টা করতে পারেন । বইটি থেকে কোডটি আটকান (নক্ষত্রের পরে) এবং এটি আপনাকে উপরের তালিকাভুক্ত ত্রুটিগুলি এবং "নিখোঁজ শেবাং" প্রদর্শন করবে। শেলচেকের কোনও ত্রুটি ছাড়াই স্ক্রিপ্টটি হ'ল:

#!/bin/sh if [ "$(date +%d -d tomorrow)" = 01 ] ; then script.sh; fi

সেই সাইটটি কাজ করে কারণ যা লেখা হয়েছিল তা হ'ল "শেল কোড"। এটি এমন একটি বাক্য গঠন যা বহু শেলগুলিতে কাজ করে।

কিছু সমস্যা যা শেলচেকের উল্লেখ নেই:

  • এটি ধরে নেওয়া হচ্ছে যে ডেট কমান্ডটি জিএনইউ তারিখ সংস্করণ। একটি -dবিকল্প যা tomorrowমান হিসাবে গ্রহণ করে (ব্যস্তবক্সে একটি -d বিকল্প রয়েছে তবে কাল তা বুঝতে পারে না এবং BSD এর -dবিকল্প রয়েছে তবে সময়ের "প্রদর্শন" সম্পর্কিত নয়)।

  • সমস্ত বিকল্পের পরে ফর্ম্যাটটি সেট করা ভাল date -d tomorrow +'%d'

  • ক্রোন শুরুর সময়টি সর্বদা স্থানীয় সময় থাকে, যা ডিএসটি (দিবালোক সংরক্ষণের সময়) সেট করা বা আনসেট না হয়ে থাকলে সঠিক দিনের গণনার চেয়ে 1 ঘন্টা আগে একটি কাজ শুরু করতে পারে।

আমরা যা করেছি তা হ'ল একটি শেল স্ক্রিপ্ট যা ক্রোন দিয়ে ডাকা যেতে পারে। আমরা প্রোগ্রামটির যুক্তিগুলি স্বীকার করার জন্য স্ক্রিপ্টটি আরও পরিবর্তন করতে পারি বা কার্যকর করার জন্য কমান্ড, এর মতো (অবশেষে, সঠিক কোড):

#!/bin/sh
[ "$#" -eq 0 ] && echo "Usage: $0 command [args]" && exit 1
[ "$(date -d tomorrow +'%d')" = 01 ] || exit 0
exec "$@"

এই স্ক্রিপ্টটি end_of_month.shকল করুন এবং ক্রનમાં কলটি কেবলমাত্র:

00 12 28-31 * * /path/to/script/end_of_month.sh command

এটি স্ক্রিপ্টটি চালিত করবে end_of_month(যা অভ্যন্তরীণভাবে পরীক্ষা করবে যে দিনটি মাসের শেষ দিন) কেবল ২৮, ২৯, ৩০, ৩১ এবং ৩১ দিনে। অন্য কোনও দিন মাসের শেষের জন্য পরীক্ষা করার দরকার নেই।

সঠিক পথটি অন্তর্ভুক্ত রয়েছে তা নিশ্চিত করুন। ক্রোন এর ভিতরে থাকা PATH ব্যবহারকারীর PATH এর মতো হবে না (সম্ভবত না)।

নোট করুন যে মাসের স্ক্রিপ্টের একটি শেষ রয়েছে যা পরীক্ষিত হয়েছে (নীচে নির্দেশিত হিসাবে) অন্যান্য অনেকগুলি ইউটিলিটি বা স্ক্রিপ্ট কল করতে পারে।

সম্পূর্ণ ক্রমান্ড লাইনের সাহায্যে ক্রোন উত্পন্ন করে এমন অতিরিক্ত সমস্যাও এড়াতে পারে:

  • ক্রোন কমান্ড লাইনটি বিভাজন করে %এমনকি কোনওটির সাথে 'বা "(কেবল \এখানে একটি কাজ) উদ্ধৃত হয় । এটি একটি সাধারণ উপায় যেখানে ক্রোন জবগুলি ব্যর্থ হয়।

কোনও পরীক্ষায় end_of_month.shস্ক্রিপ্ট সঠিকভাবে কাজ করে কিনা তা পরীক্ষা করতে পারবেন (মাসের শেষে অপেক্ষা না করে এটি কাজ করে না এটি আবিষ্কার করে) নকল সময় দিয়ে পরীক্ষা করে:

$ faketime 2018/10/31 ./end_of_month echo "Command will be executed...."
Command will be executed....

অ্যাস্ট-ওপেন date(বা dateksh93 এর বিল্টিন যদি ksh93 অ্যাস্ট-ওপেনের অংশ হিসাবে নির্মিত হয়েছিল) সমর্থন করে date -d tomorrow +%sবা date +%s tomorrow)।
স্টাফেন চেজেলাস

2
অভিজ্ঞতা প্রমাণ করেছে (বহুবার) যে নির্ধারিত কাজটি কাজ করে না তা খুঁজে পাওয়ার জন্য মাসের শেষ অবধি অপেক্ষা করার চেয়ে ফেকটাইম দিয়ে সঠিকভাবে স্ক্রিপ্টটি পরীক্ষা করা অনেক ভাল। অভ্যাসটির মতো * * * * * echo "$(date -u +'date %c')" >>~/testfileকাজ আবিষ্কার করার মতো কারণ কেউ উদ্ধৃতি দিতে ভুলে গেছে \%(যা প্রতি মাসে মাত্র একটি চেষ্টা করা সম্ভব হলে তা ডিবাগ করা কঠিন হয়ে পড়ে)। @ কুসালানন্দ
ইসহাক

8

ধরে নিচ্ছি যে সিনট্যাক্স ত্রুটিগুলি স্থির হয়েছে, এবং কমান্ডটি কম ভার্বোস হওয়ার জন্য কিছুটা সংশোধন করেছে:

00 12 28-31 * * [ "$( date -d tomorrow +\%d )" != "01" ] || command1

দুই-অঙ্কের নম্বর হিসাবে আগামীকালের তারিখ পাওয়ার জন্য এটি চলে date +%d -d tomorrow(এটি জিএনইউ dateযা ব্যবহৃত হয় তা ধরে নেওয়া )। যদি সংখ্যাটি না হয় 01তবে আজকের মাসের শেষ দিনটি নয়। সেক্ষেত্রে পরীক্ষাগুলি সফল হয় এবং কার্যকর command1হয় না । এই দিন দুপুরে এই কাজটি চালানো হয় যেগুলি সম্ভবত মাসের শেষ দিন হতে পারে।

মূল আদেশ:

00 12 * * * if [`date +%d -d tomorrow` = 01 ] ; then ; command1

এটিতে কয়েকটি সমস্যা রয়েছে:

  • এর পরে কোনও স্থান নেই [
  • একটি ;সরাসরি পর then
  • %ক্রোন জব স্পেসিফিকেশন বিশেষ এবং এ হিসাবে এড়াতে হবে \%(দেখুন man 5 crontab)।
  • fiএর সাথে শেষ পর্যন্ত কোনও ফাইনাল নেই if

2
[ ... ] && command1পরিবর্তে ব্যবহার করার ক্ষেত্রে সমস্যাটি if...হ'ল যে দিনগুলি মাসের শেষ দিন নয়, ক্রোন জবটি একটি শূন্য-বহির্গমন স্থিতির সাথে শেষ হবে এবং সেই ব্যর্থতার কথা জানাতে হতে পারে। [ "$(...)" != 01 ] || command1সমস্যা এড়ানোর জন্য আরেকটি উপায় ব্যবহার করা।
স্টাফেন চেজেলাস

1
মূল কোড সহ আরেকটি সমস্যা হল ;মধ্যে thenএবং command1
স্টাফেন চেজেলাস

@ স্টাফেনচাজেলাস আমি ওয়ান-লাইনার অপছন্দ করার আরেকটি কারণ, সেগুলি পড়া কঠিন।
কুসালানন্দ

কমান্ডের একটানা রান করার সময়ের পার্থক্যটি (২৪ ঘন্টা) দিনের পূর্ণসংখ্যার পরিমাণ নাও হতে পারে কারণ একটি ডিএসটি পরিবর্তন ক্রোনটির শুরুর সময়কে বদলে দেবে।
ইসহাক

3
@ ক্যাট আপনি কীভাবে উদ্ধৃত করেছেন তা "বা তাতে কিছু যায় আসে না বা '(ব্যতীত \), শতাংশ চিহ্নটি ক্রোনকে %দুটি ভাগে বিভক্ত করে দেবে। ব্যর্থ হওয়ার জন্য ক্রোন পাওয়ার এটি একটি সাধারণ উপায়।
আইজাক

-1

প্রতি মাসের শেষ দিনে নির্দিষ্ট সময় নির্ধারণের জন্য, আপনি চেষ্টা করতে পারেন: 0 0 15,L * *

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