পরীক্ষার জন্য আমি কীভাবে ব্যাশ ব্যবহার করতে পারি এবং একসাথে আদেশগুলি খুঁজে পেতে পারি?


25

ক্র্যাশ লগ সহ আমার একটি ডিরেক্টরি রয়েছে এবং আমি ফাইন্ড কমান্ডের উপর ভিত্তি করে ব্যাশ স্ক্রিপ্টে শর্তযুক্ত বিবৃতি ব্যবহার করতে চাই।

লগ ফাইলগুলি এই ফর্ম্যাটে সংরক্ষণ করা হয়:

/var/log/crashes/app-2012-08-28.log
/var/log/crashes/otherapp-2012-08-28.log

আমি চাই যদি বিবৃতিটি কেবলমাত্র সত্য ফিরে আসে তবে নির্দিষ্ট অ্যাপের জন্য ক্র্যাশ লগ থাকে যা শেষ 5 মিনিটে পরিবর্তিত হয়েছে। findকমান্ড যে আমি ব্যবহার করেন হল:

find /var/log/crashes -name app-\*\.log -mmin -5

আমি নিশ্চিত না যে কীভাবে এটি একটি ifবিবৃতিতে সঠিকভাবে অন্তর্ভুক্ত করা যায় । আমি মনে করি এটি কার্যকর হতে পারে:

if [ test `find /var/log/crashes -name app-\*\.log -mmin -5` ] then
 service myapp restart
fi

কয়েকটি অঞ্চল রয়েছে যেখানে আমি অস্পষ্ট:

  • আমি যদি পতাকাগুলি দেখেছি তবে আমার কোনটি ব্যবহার করা উচিত তা নিশ্চিত নই।
  • আমার কি testনির্দেশিকা দরকার বা আমার সন্ধানের আদেশের ফলাফলের বিরুদ্ধে সরাসরি প্রক্রিয়া করা উচিত, অথবা find... | wc -lপরিবর্তে কোনও লাইন গণনা পেতে ব্যবহার করা উচিত?
  • এই প্রশ্নের উত্তর দেওয়ার জন্য 100% প্রয়োজনীয় নয়, তবে testকি রিটার্ন কোডের বিপরীতে পরীক্ষা করার জন্য? তারা অদৃশ্য সাজানোর রয়েছে - বাইরে stdout/ stderr? আমি manপৃষ্ঠাটি পড়েছি তবে কখন ব্যবহার করব testএবং কীভাবে এটি ডিবাগ করা যায় সে সম্পর্কে এখনও আমি অস্পষ্ট ।

সাধারণ ক্ষেত্রে আসল উত্তরটি ব্যবহার করা find ... -exec। উদাহরণস্বরূপ কমান্ডগুলি নীচে দেখুন কেন ফাইন্ডের আউটপুটটি খারাপ অভ্যাসের উপর নির্ভর করে?
ওয়াইল্ডকার্ড

@ উইল্ডকার্ড - দুর্ভাগ্যক্রমে এটি সাধারণ ক্ষেত্রে সমাধান করে না : একাধিক ম্যাচ থাকলে এবং কাজটি কেবল একবার চালানোর প্রয়োজন হলে এটি কাজ করে না, এবং যখন যখন আপনাকে কোনও ক্রিয়া চালানোর দরকার হয় তখন এটি কাজ করে না মিল নেই. প্রাক্তনটি ব্যবহার করে সমাধান করা যেতে পারে ... -exec command ';' -quit, তবে আমি বিশ্বাস করি না যে ফলাফলটি বিশ্লেষণ করা ছাড়া দ্বিতীয়টির জন্য কোনও সমাধান আছে। এছাড়াও, উভয় ক্ষেত্রেই, ফলাফলের পার্সিংয়ের সাথে প্রাথমিক সমস্যা find(অর্থাত্ ফাইলের অক্ষরগুলির মধ্যে ডেলিফিটরগুলি পৃথক করতে অক্ষম) প্রযোজ্য না, কারণ এই ক্ষেত্রে আপনাকে ডিলিমিটারগুলি খুঁজে পাওয়ার দরকার নেই।
জুলাই

উত্তর:


27

[এবং testপ্রতিশব্দ ( [প্রয়োজন ব্যতীত ]), তাই আপনি ব্যবহার করতে চান না [ test:

[ -x /bin/cat ] && echo 'cat is executable'
test -x /bin/cat && echo 'cat is executable'

testশর্তটি সত্য হলে শূন্য প্রস্থান স্থিতি প্রদান করে, অন্যথায় ননজারো। এটি প্রস্থান স্থিতি পরীক্ষা করতে কোনও প্রোগ্রাম দ্বারা আসলে প্রতিস্থাপন করা যেতে পারে, যেখানে 0 সাফল্য এবং অ-শূন্যকে ব্যর্থতা নির্দেশ করে:

# echoes "command succeeded" because echo rarely fails
if /bin/echo hi; then echo 'command succeeded'; else echo 'command failed'; fi

# echoes "command failed" because rmdir requires an argument
if /bin/rmdir; then echo 'command succeeded'; else echo 'command failed'; fi

যাইহোক, উপরের সমস্ত উদাহরণগুলি কেবল প্রোগ্রামের প্রস্থান স্থিতির বিপরীতে পরীক্ষা করে এবং প্রোগ্রামটির আউটপুট উপেক্ষা করে।

কারণ find, আপনাকে যদি কোনও আউটপুট উত্পন্ন হয়েছিল কিনা তা পরীক্ষা করতে হবে। -nএকটি খালি খালি স্ট্রিংয়ের জন্য পরীক্ষা:

if [[ -n $(find /var/log/crashes -name "app-*.log" -mmin -5) ]]
then
    service myapp restart
fi

পরীক্ষা আর্গুমেন্ট একটি পূর্ণ তালিকা invoking দ্বারা উপলব্ধ help testbashকমান্ড।

আপনি যদি ব্যবহার করছেন bash(এবং না sh), আপনি ব্যবহার করতে পারেন [[ condition ]], যখন আপনার অবস্থার মধ্যে স্পেস বা অন্যান্য বিশেষ কেস রয়েছে তখন এটি আরও অনুমানযোগ্য আচরণ করে। অন্যথায় এটি সাধারণত ব্যবহারের মতো [ condition ]। আমি [[ condition ]]এই উদাহরণটি ব্যবহার করেছি , যখনই সম্ভব আমি করি।

আমিও পরিবর্তিত `command`করতে $(command), যা সাধারণত একভাবে আচরণ করবে কিন্তু নেস্টেড কমান্ড দিয়ে সুন্দর হয়।


echoব্যর্থ হতে পারে: চেষ্টা করুন echo 'oops' > /dev/full
ডার্বোবার্ট

এই উত্তরটি সমস্যার মূলটিকে ঘিরে ধরে তবে করণীয়ভাবে এটি কী তা উল্লেখ করা এড়ানো যায়।
বাহামা

9

findকোনও ত্রুটি না থাকলে সফলভাবে প্রস্থান করবেন, সুতরাং এটির কোনও প্রস্থান পাওয়া যায় কিনা তা জানতে আপনি এটির প্রস্থান স্থিতিতে গুনতে পারবেন না। তবে, যেমনটি আপনি বলেছিলেন, আপনি এটি কতগুলি ফাইল খুঁজে পেয়েছেন তা গণনা করতে পারেন এবং সেই নম্বরটি পরীক্ষা করতে পারেন।

এটি এমন কিছু হবে:

if [ $(find /var/log/crashes -name 'app-*.log' -mmin -5 | wc -l) -gt 0 ]; then
    ...
fi

test(ওরফে [) কমান্ডগুলির ত্রুটি কোডগুলি যাচাই করে না, এটি পরীক্ষা করার জন্য একটি বিশেষ বাক্য গঠন করে এবং তারপরে পরীক্ষায় সফল হয়, বা অন্যথায় 1 হলে একটি এরর কোড সহ প্রস্থান করে। এটি হ'ল ifআপনি যা আদেশটি পাঠিয়েছেন তার ত্রুটি কোডটি যাচাই করে এবং এর ভিত্তিতে এর বডিটি কার্যকর করে।

দেখ man test (অথবা help testযদি আপনি ব্যবহার bash), এবং help if(Ditto)।

এই ক্ষেত্রে, wc -lএকটি সংখ্যা আউটপুট হবে। যদি সংখ্যাটি এর চেয়ে বেশি হয় তবে আমরা পরীক্ষার জন্য testবিকল্পটি ব্যবহার করি । যদি তা হয়, (বা ) প্রস্থান কোড সহ ফিরে আসবে । সেই প্রস্থান কোডটিকে সাফল্য হিসাবে ব্যাখ্যা করবে এবং এটি কোডটি তার দেহের অভ্যন্তরে চালিত করবে।-gt0test[0if


1

এই হবে

if [ -n "$(find /var/log/crashes -name app-\*\.log -mmin -5)" ]; then

অথবা

if test -n "$(find /var/log/crashes -name app-\*\.log -mmin -5)"; then

কমান্ডগুলি testএবং [ … ]একেবারে সমার্থক। পার্থক্য কেবলমাত্র তাদের নাম এবং এটির শেষ যুক্তি হিসাবে এটি [বন্ধ ]হওয়ার প্রয়োজন । সর্বদা হিসাবে, কমান্ড প্রতিস্থাপনের চারপাশে ডাবল উদ্ধৃতি ব্যবহার করুন, অন্যথায় কমান্ডের আউটপুট findশব্দের মধ্যে বিভক্ত হয়ে যাবে এবং এখানে যদি একাধিক ফাইলের মিল থাকে তবে (এবং কোনও যুক্তি না থাকলে [ -n ]সত্য) , যদিও আপনি চান [ -n "" ]যা মিথ্যা)।

Ksh, bash এবং zsh এ তবে ছাই নয়, আপনি ব্যবহার করতে পারেন [[ … ]]যার বিভিন্ন বিভাজন বিধি রয়েছে: [এটি একটি সাধারণ কমান্ড, অন্যদিকে [[ … ]]পৃথক পার্সিং নির্মাণ। আপনার ভিতরে ডাবল উদ্ধৃতি প্রয়োজন নেই [[ … ]](যদিও তারা আঘাত করে না)। আপনার এখনও ;কমান্ডের পরে প্রয়োজন ।

if [[ -n $(find /var/log/crashes -name app-\*\.log -mmin -5) ]]; then

এটি সম্ভাব্যভাবে অদক্ষ হতে পারে: যদি এখানে অনেকগুলি ফাইল থাকে তবে /var/log/crashesসেগুলি সমস্ত অনুসন্ধান করবে। এটি কোনও মিল খুঁজে পাওয়ার সাথে সাথে বা তার ঠিক পরে খুঁজে পাওয়া উচিত। জিএনইউ অনুসন্ধানের সাথে (এম্বেডড লিনাক্স, সিগউইন) -quitপ্রাথমিক ব্যবহার করুন ।

if [ -n "$(find /var/log/crashes -name app-\*\.log -mmin -5 -print -quit)" ]; then

অন্যান্য সিস্টেম, পাইপ দিয়ে findমধ্যে headথেকে অন্তত প্রথম খেলা শেষে শীঘ্রই প্রস্থান (খোঁজ একটি ভাঙা পাইপ মারা হবে)।

if [ -n "$(find /var/log/crashes -name app-\*\.log -mmin -5 -print | head -n 1)" ]; then

( head -c 1আপনার headআদেশ যদি এটি সমর্থন করে তবে আপনি এটি ব্যবহার করতে পারেন ))


বিকল্পভাবে, zsh ব্যবহার করুন।

crash_files=(/var/log/crashes/**/app-*.log(mm-5[1]))
if (($#crash_files)); then


0
find /var/log/crashes -name app-\*\.log -mmin -5 -exec service myapp restart ';' -quit

এখানে একটি উপযুক্ত সমাধান।

-exec service myapp restart ';'কারণ findকমান্ড ডাকা যে আপনি বরং কিছু ব্যাখ্যা করার শেল প্রয়োজন চেয়ে সরাসরি চালানোর জন্য, চাই।

-quitfindকমান্ডটি প্রক্রিয়া করার পরে প্রস্থান করার কারণ হয়ে থাকে, সুতরাং মানদণ্ডের সাথে মেলে এমন একাধিক ফাইল যদি ঘটে থাকে তবে কমান্ডটি আবার কার্যকর করা আটকাবে।

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