কোনও কমান্ড ত্রুটিতে আমার বাশ স্ক্রিপ্ট অটো চালানোর কোনও উপায় আছে কি?


12

আমি একটি শেল স্ক্রিপ্ট লিখছি যা একগুচ্ছ কমান্ড করতে হবে এবং প্রতিটি কমান্ড প্রতিটি পূর্ববর্তী কমান্ডের উপর নির্ভর করে। যদি কোনও কমান্ড ব্যর্থ হয় তবে পুরো স্ক্রিপ্টটি ব্যর্থ হবে এবং আমি একটি প্রস্থান ফাংশন বলি। আমি প্রতিটি কমান্ডের প্রস্থান কোড চেক করতে পারি তবে আমি ভাবছি যে মোড আছে কিনা আমি সক্ষম করতে পারি বা স্বয়ংক্রিয়ভাবে তা করার জন্য বাশ পাওয়ার কোনও উপায় আছে কিনা I

উদাহরণস্বরূপ, এই আদেশগুলি গ্রহণ করুন:

cd foo || myfunc
rm a || myfunc
cd bar || myfunc
rm b || myfunc


এই কমান্ডগুলি কার্যকর করার আগে আমি কোনওভাবে শেলকে সংকেত দিতে পারি যে এর মধ্যে কোনওটি ব্যর্থ হলে এটি মাইফাঙ্ককে কল করা উচিত, যাতে পরিবর্তে আমি আরও কিছু ক্লিনার লিখতে পারি:

cd foo
rm a
cd bar
rm b

উত্তর:


13

কোনও কমান্ড শূন্যের চেয়ে বেশি স্থিতি ফিরিয়ে দেয় এবং বেরিয়ে যাওয়ার সময় আপনার ফাংশনটি সম্পাদন করে আপনি আপনার স্ক্রিপ্টটি প্রস্থান করতে বাশ ট্র্যাপ ইআরআর ব্যবহার করতে পারেন ।

কিছুটা এইরকম:

myfunc() {
  echo 'Error raised. Exiting!'
}

trap 'myfunc' ERR

# file does not exist, causing error
ls asd
echo 123

নোট করুন যে ব্যাশ ট্র্যাপ ERR অন্তর্নিহিত করে set -o errexitবা set -eএটি পসিক্স নয়।

এবং ERRট্র্যাপটি কার্যকর করা হয় না যদি ব্যর্থ কমান্ড তত্ক্ষণাত কমান্ড তালিকার একটি অংশ থাকে untilবা whileকীওয়ার্ড হয়, পরীক্ষার অংশ ifবা elifসংরক্ষিত শব্দের পরে পরীক্ষার অংশ, চালানো আদেশের অংশ &&বা ||তালিকায় ব্যবহৃত হয়, বা যদি কমান্ডের রিটার্ন স্ট্যাটাস ব্যবহার করে উল্টানো হয় !


1

একটি (সম্ভবত) গৃহীত উত্তরের উপর সহজ প্রকরণ:

  1. set -e একটি তালিকা কার্যকর করতে বাতিল করতে একটি কমান্ডের ব্যর্থতার কারণ হিসাবে ব্যবহার করুন ।
  2. কেবল আপনার আদেশগুলি তালিকাভুক্ত করুন।
  3. একটি ব্যবহার করুন if- then- elseআপনার ত্রুটি-হ্যান্ডলিং কমান্ড (গুলি) চালানো বিবৃতি। এই শেষ টুকরাটি কিছুটা জটিল। ঘড়ি:
সেট -ই
যদি
    সেমিডিডি 1                         # যেমন, সিডি ফু
     সেন্টিমিডি 2                         # যেমন, আরএম একটি
     সেমিডি 3                         # উদা, সিডি বার
     সেন্টিমিডি 4                         # যেমন, আরএম বি
তারপর
    সেট + ই
    সাফল্যের জন্য আদেশ (যদি থাকে)
আর
    সেট + ই
    myfunc
    অন্যান্য কমান্ডগুলি ব্যর্থতার পরে (যদি থাকে) 
ফাই করতে হবে

চতুর অংশ যে আপনি আপনার কমান্ড করা হয় মধ্যে অংশif এর if- then- else, না thenঅংশ বা elseঅংশ। স্মরণ করুন যে বিবৃতিটির বাক্য ifগঠনটি রয়েছে

যদি  তালিকা ; তারপরে  তালিকা ; [এলিফ  তালিকা ; তারপরে  তালিকা ; ] ... [অন্য  তালিকা ; ] ফাই 
   ↑↑↑↑
set -eশেল যে, যদি বলে ( ) ব্যর্থ হলে, এটি যেতে উচিত নয় এবং চালানো ( ), এবং তাই লাইন নিচে। শেল স্ক্রিপ্টের বাইরেরতম স্তরের কোনও কমান্ডের ক্ষেত্রে যদি এটি ঘটে, শেলটি প্রস্থান করবে। যাইহোক, যেহেতু · · · একটি (যৌগিক) তালিকা অনুসরণ করে , সুতরাং এই চারটি কমান্ডের কোনওটিরই ব্যর্থতা কেবল পুরো তালিকাটিকে ব্যর্থ করে দেয় - যার ফলে এই ধারাটি কার্যকর করা হয়। যদি চারটি কমান্ড সফল হয় তবে ক্লজটি কার্যকর করা হবে।cmd1cd foocmd2rm acmd1cmd2cmd3cmd4ifelsethen

উভয় ক্ষেত্রেই, প্রথম জিনিস আপনি করতে হবে নিষ্ক্রিয় (বন্ধ করুন) সম্ভবত হয় eকরে বিকল্প set +e। অন্যথায়, কোনও কমান্ড myfuncব্যর্থ হলে স্ক্রিপ্টটি জল থেকে বের হয়ে যেতে পারে ।

set -eহয় উল্লেখ এবং POSIX স্পেসিফিকেশন বর্ণিত


0

আপনার শব্দটি নেওয়া " প্রতিটি কমান্ড প্রতিটি পূর্ববর্তী কমান্ডের উপর নির্ভর করে any কোনও কমান্ড যদি পুরো স্ক্রিপ্টে ব্যর্থ হয় তবে " আক্ষরিক অর্থে, আমি মনে করি ত্রুটিগুলি নিরাময়ের জন্য আপনার কোনও বিশেষ ফাংশনের প্রয়োজন নেই।

আপনার যা দরকার তা হ'ল &&অপারেটর এবং ||অপারেটরের সাথে আপনার কমান্ডগুলি শৃঙ্খলাবদ্ধ করা , যা আপনি লিখেছেন ঠিক তা করে।

উদাহরণস্বরূপ, এই শৃঙ্খলাটি ভেঙে " পূর্ববর্তী কোনও কমান্ড ভঙ্গ হলে" কিছু ভুল হয়েছে "মুদ্রণ করবে (বাশ বাম থেকে ডানে পড়বে )

cd foo && rm a && cd bar && rm b || echo "something went wrong"

প্রকৃত উদাহরণ (আমি একটি সত্যিকারের ডেমোর জন্য দির ফু, ফাইল এ, ডায়ার বার এবং ফাইল বি তৈরি করেছি):

gv@debian:/home/gv/Desktop/PythonTests$ cd foo && rm a && cd bar && rm bb || echo "something is wrong"
rm: cannot remove 'bb': No such file or directory
something is wrong #mind the error in the last command

gv@debian:/home/gv/Desktop/PythonTests$ cd foo && rm aa && cd bar && rm b || echo "something is wrong"
rm: cannot remove 'aa': No such file or directory
something is wrong #mind the error in second command in the row

এবং সবশেষে যদি সমস্ত কমান্ড সফলভাবে কার্যকর করা হয় (প্রস্থান কোড 0), স্ক্রিপ্টটি কেবল চলে:

gv@debian:/home/gv/Desktop/PythonTests$ cd foo && rm a && cd bar && rm b || echo "something is wrong"
gv@debian:/home/gv/Desktop/PythonTests/foo/bar$ 
# mind that the error message is not printed since all commands were successful.

কী মনে রাখা গুরুত্বপূর্ণ তা হল যে পূর্ববর্তী কমান্ডটি কোড 0 দিয়ে বের হয়ে গেলে & কমান্ড ব্যবহার করে পরবর্তী কমান্ড কার্যকর করা হয় যার অর্থ বাশ মানে সাফল্য।

যদি কোনও কমান্ড শৃঙ্খলে ভুল হয়ে যায় তবে আদেশ / লিপি / যা যা অনুসরণ করে || মৃত্যুদন্ড কার্যকর করা হবে।

এবং কেবল রেকর্ডের জন্য, যদি কমান্ডটি ভেঙে গেছে তার উপর নির্ভর করে যদি আপনার বিভিন্ন ক্রিয়াকলাপ করা দরকার হয় তবে আপনি এটি $?পূর্ববর্তী কমান্ডের প্রস্থান কোডটির মান পর্যালোচনা করে ক্লাসিক স্ক্রিপ্ট দিয়েও করতে পারেন (কমান্ড সফলভাবে কার্যকর হলে শূন্য ফিরে আসে) বা কমান্ড ব্যর্থ হলে অন্যান্য ধনাত্মক সংখ্যা)

উদাহরণ:

for comm in {"cd foo","rm a","cd bbar","rm b"};do  #mind the error in third command
eval $comm
    if [[ $? -ne 0 ]];then 
        echo "something is wrong in command $comm"
        break
    else 
    echo "command $comm executed succesful"
    fi
done

আউটপুট:

command cd foo executed succesfull
command rm a executed succesfull
bash: cd: bbar: No such file or directory
something is wrong in command cd bbar

পরামর্শ: আপনি প্রয়োগ করে "বাশ: সিডি: বার: এই জাতীয় কোনও ফাইল ..." দমন করতে পারেন eval $comm 2>/dev/null

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