কমান্ড ব্যর্থ হলে কীভাবে প্রস্থান করবেন?


222

আমি শেল-স্ক্রিপ্টিংয়ের নূব। আমি কোনও বার্তা মুদ্রণ করতে চাই এবং কোনও কমান্ড ব্যর্থ হলে আমার স্ক্রিপ্টটি প্রস্থান করতে চাই। আমি চেষ্টা করেছিলাম:

my_command && (echo 'my_command failed; exit)

কিন্তু এটা কাজ করে না. এটি স্ক্রিপ্টে এই লাইনটি অনুসরণ করে নির্দেশগুলি কার্যকর করে চলে। আমি উবুন্টু এবং বাশ ব্যবহার করছি।


5
আপনি কি অবিরত উদ্ধৃতিটিকে একটি সিনট্যাক্স ত্রুটি হিসাবে চিহ্নিত করতে চেয়েছিলেন যা ব্যর্থ / প্রস্থান করতে পারে? যদি তা না হয়, আপনার উদাহরণে উদ্ধৃতিটি বন্ধ করা উচিত।
hobs

উত্তর:


406

চেষ্টা করুন:

my_command || { echo 'my_command failed' ; exit 1; }

চারটি পরিবর্তন:

  • পরিবর্তন &&করুন||
  • { }জায়গায় ব্যবহার করুন( )
  • ;পরে exitএবং পরিচয় করিয়ে দিন
  • পরে {এবং আগে স্পেস}

যেহেতু আপনি বার্তাটি মুদ্রণ করতে চান এবং কেবল তখনই প্রস্থান করতে চান যখন কমান্ডটি ব্যর্থ হয় (অ-শূন্য মান সহ প্রস্থান করে) আপনার কোনও প্রয়োজন ||নেই &&

cmd1 && cmd2

সফল cmd2হলে চালিত হবে cmd1(প্রস্থান মান 0)। যেখানে হিসাবে

cmd1 || cmd2

চালানো হবে cmd2যখন cmd1(প্রস্থান মান নন-জিরো) ব্যর্থ।

এর সাহায্যে ( )তাদের ভিতরে থাকা কমান্ডটি একটি সাব-শেলটিতে চালিত হয় এবং exitসেখান থেকে একটি কল করার ফলে আপনি উপ-শেলটি প্রস্থান করতে পারবেন এবং আপনার মূল শেলটি নয়, সুতরাং আপনার আসল শেলটিতে কার্যকর হওয়া অব্যাহত রয়েছে।

এই ব্যবহার কাটিয়ে উঠতে { }

শেষ দুটি পরিবর্তন বশ দ্বারা প্রয়োজনীয়।


4
এটি "বিপরীত" বলে মনে হচ্ছে। যদি কোনও ফাংশন "সফল" হয় তবে এটি 0 প্রদান করে এবং যদি এটি "ব্যর্থ" হয় তবে এটি শূন্য-বহিরাগত প্রত্যাবর্তন করে সুতরাং && এর প্রথমার্ধ যখন শূন্য-শূন্য ফিরে আসে তখন মূল্যায়নের আশা করা যেতে পারে। এর অর্থ এই নয় যে উপরের উত্তরটি ভুল no এটি সঠিক নয়। && এবং || স্ক্রিপ্টগুলিতে সাফল্যের ভিত্তিতে কাজ ফিরতি মূল্যের উপর নয়।
ক্যাশকো

7
এটি বিপরীত বলে মনে হচ্ছে, তবে এটি পড়ুন এবং এর
অর্থটি

2
এর পিছনে যুক্তিটি হ'ল ভাষা শর্ট সার্কিট মূল্যায়ন (এসসিই) ব্যবহার করে। এসসিই এর সাথে, চ অভিব্যক্তিটি "p বা q" ফর্মের, এবং pকে সত্য বলে মূল্যায়ন করা হয়, তবে q এর দিকে তাকানোর কোনও কারণ নেই। যদি অভিব্যক্তিটি "পি ও কিউ" ফর্মের হয়, এবং p কে মিথ্যা হিসাবে মূল্যায়ন করা হয়, তবে q এর দিকে দেখার কোনও কারণ নেই। এর কারণ দ্বিগুণ: 1) এর দ্রুত, স্পষ্ট কারণ এবং 2) এটি কিছু ধরণের ত্রুটিগুলি এড়িয়ে চলে (উদাহরণস্বরূপ: "যদি x! = 0 এবং 10 / x> 5" এসসিই না থাকে তবে ক্র্যাশ হবে) )। এটির মতো কমান্ড লাইনে এটি ব্যবহারের ক্ষমতা হ'ল একটি সুখী পার্শ্ব-প্রতিক্রিয়া।
ব্যবহারকারী 2635263

2
আমি এসটিডিআরআর প্রতিধ্বনি দেওয়ার প্রস্তাব দিচ্ছি:{ (>&2 echo 'my_command failed') ; exit 1; }
12:48

127

অন্যান্য উত্তরগুলি সরাসরি প্রশ্নটি ভালভাবে কভার করেছে তবে আপনি ব্যবহারে আগ্রহীও হতে পারেন set -e। এটির সাথে, যে কোনও কমান্ড ব্যর্থ হয় ( ifপরীক্ষার মতো নির্দিষ্ট প্রসঙ্গে বাইরে ) স্ক্রিপ্টটি বাতিল করতে পারে। নির্দিষ্ট স্ক্রিপ্টগুলির জন্য, এটি খুব দরকারী।


3
দুর্ভাগ্যক্রমে, এটিও খুব বিপজ্জনক - set -eএটি কখন কার্যকর হয় এবং কখন হয় না সে সম্পর্কে নিয়মের একটি দীর্ঘ এবং বিনোদনের সেট রয়েছে। (যদি কেউ দৌড়ে যায় if yourfunction; then ...তবে set -eকখনই ভেতরে গুলি চালায় নাyourfunction বা যে কোনও কিছু কল করে তা , কারণ সেই কোডটি "পরীক্ষিত" হিসাবে বিবেচিত হয়)। এটি এবং অন্যান্য সমস্যাগুলি নিয়ে আলোচনা করে বাশএফএকিউ # 105 এর অনুশীলন বিভাগটি দেখুন (যার মধ্যে কয়েকটি কেবল নির্দিষ্ট শেল সংস্করণে প্রযোজ্য তাই আপনার স্ক্রিপ্টটি চালানোর জন্য ব্যবহৃত প্রতিটি প্রকাশের বিরুদ্ধে পরীক্ষা করা আপনার অবশ্যই নিশ্চিত হওয়া উচিত)।
চার্লস ডাফি

67

এছাড়াও নোট করুন, প্রতিটি কমান্ডের প্রস্থান স্থিতি শেল ভেরিয়েবল $? In এ সংরক্ষণ করা হয়, যা আপনি কমান্ডটি চালানোর সাথে সাথেই পরীক্ষা করতে পারবেন। একটি শূন্য-স্থিতি ব্যর্থতা নির্দেশ করে:

my_command
if [ $? -eq 0 ]
then
    echo "it worked"
else
    echo "it failed"
fi

10
এটি কেবল আমার_কম্যান্ড দ্বারা প্রতিস্থাপন করা যেতে পারে, এখানে টেস্ট কমান্ড ব্যবহার করার দরকার নেই।
বার্ট সাস

5
+1 কারণ আমি মনে করি যে এই বিকল্পের তালিকা তৈরির জন্য আপনাকে শাস্তি দেওয়া উচিত নয় - এটি টেবিলে থাকা উচিত - যদিও এটি অত্যন্ত কুৎসিত এবং আমার অভিজ্ঞতার মধ্যে পরীক্ষার প্রকৃতি অবহেলা না করে অন্য কমান্ড চালানো খুব সহজ (সম্ভবত আমি ') m just stupid)।
টনি ডেলরয়

1
@ বার্টাসাস যদি কমান্ডটি দীর্ঘ হয় তবে এটি নিজের লাইনে রাখাই ভাল। এটি স্ক্রিপ্টটি আরও পঠনযোগ্য করে তোলে।
মাইকেল

@ মাইকেল, এটি লাইন জুড়ে নির্ভরতা তৈরি করে না, যেখানে লাইন বি বোঝার আগে আপনাকে লাইন এ-তে কী ঘটেছিল তা জানতে হবে (বা আরও খারাপ কিছু, এটি যুক্ত করা নিরাপদ যে কিছু জানার আগে আপনি জানবেন যে লাইনে বিতে কী ঘটবে লাইন এ এর ​​শেষে নতুন) আমি অনেকবার দেখেছি কেউ এ যুক্ত করেছে echo "Just finished step A", না জেনেও যে এটি পরে পরীক্ষা করা হবে সেটি echoওভাররোট করে $?
চার্লস ডাফি

67

আপনি যদি আপনার স্ক্রিপ্টের সমস্ত কমান্ডের জন্য আচরণটি চান, কেবল যুক্ত করুন

  set -e 
  set -o pipefail

স্ক্রিপ্টের শুরুতে। এই যুগল বিকল্পগুলি ব্যাশ ইন্টারপ্রেটারকে প্রস্থান করতে বলবে যখনই কোনও শূন্য-বহির্গমন কোড সহ কোনও কমান্ড ফিরে আসে।

যদিও এটি আপনাকে প্রস্থান বার্তা প্রিন্ট করার অনুমতি দেয় না।


8
trapব্যাশ অন্তর্নির্মিত কমান্ডটি ব্যবহার করে আপনি প্রস্থান করার সময় কমান্ডগুলি চালাতে পারেন ।
গ্যাভিন স্মিথ

এটি এক্সওয়াই প্রশ্নের উত্তর।
jwg

5
জোড়ার চেয়ে স্বতন্ত্রভাবে কমান্ডগুলি কী তা বোঝাতে আকর্ষণীয় হতে পারে। বিশেষত যেহেতু set -o pipefailপছন্দসই আচরণ নাও হতে পারে। এখনও এটি নির্দেশ করার জন্য ধন্যবাদ!
এন্টোইন পিনসার্ড 26'17

3
set -eমোটেই নির্ভরযোগ্য, ধারাবাহিক বা অনুমানযোগ্য নয়! এ সম্পর্কে নিজেকে বোঝানোর জন্য, বাশফ্যাঙ্ক # 105 এর অনুশীলন বিভাগ বা ইনুলিউম.ডি / scমাস্কেক / ভার্ভিস / সেট- এ বিভিন্ন শেলের আচরণের সাথে তুলনা করার টেবিলটি পর্যালোচনা করুন
চার্লস ডাফি

14

আমি নিম্নলিখিত আইডিয়ম হ্যাক করেছি:

echo "Generating from IDL..."
idlj -fclient -td java/src echo.idl
if [ $? -ne 0 ]; then { echo "Failed, aborting." ; exit 1; } fi

echo "Compiling classes..."
javac *java
if [ $? -ne 0 ]; then { echo "Failed, aborting." ; exit 1; } fi

echo "Done."

প্রতিটি কমান্ডকে তথ্যমূলক প্রতিধ্বনির পূর্বে এবং একই কমান্ডের সাথে প্রতিটি কমান্ড অনুসরণ করুন
if [ $? -ne 0 ];...। (অবশ্যই আপনি চাইলে সেই ত্রুটি বার্তাটি সম্পাদনা করতে পারেন))


এটি একটি ফাংশন হিসাবে সংজ্ঞায়িত করা যেতে পারে, সুতরাং এটি পুনরায় ব্যবহার করুন।
এরিক ওয়াং

1
'যদি [$? -ne 0]; তারপরে ... ফাই 'একটি জটিল উপায়' ||
কেভিন

if ! javac *.java; then ...- কেন কিছুতেই বিরক্ত করবেন $??
চার্লস ডাফি

চার্লস - কারণ আমি সর্বোপরি একটি মধ্যম বাশ স্ক্রিপ্টার :)
গ্রান্ট বার্চমিয়ার

10

সরবরাহিত my_commandনীতিগতভাবে ডিজাইন করা হয়েছে, অর্থাৎ সফল হলে 0 প্রদান করে, তবে &&আপনি যা চান তার ঠিক বিপরীত। তুমি চাও||

এছাড়াও মনে রাখবেন যে (ব্যাশে আমার কাছে ঠিক মনে হচ্ছে না, তবে আমি যেখানে থেকে চেষ্টা করতে পারি না। আমাকে বলুন.

my_command || {
    echo 'my_command failed' ;
    exit 1; 
}

আইআইআরসি, আপনার প্রতিটি লাইনের পরে সেমিকোলন দরকার {}
অ্যালেক্স হাওয়ানস্কি

9
@ অ্যালেক্স: তারা আলাদা লাইনে থাকলে না।
পরবর্তী বিজ্ঞপ্তি না হওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

5

আপনি যদি প্রস্থান ত্রুটির স্থিতি সংরক্ষণ করতে চান এবং প্রতি লাইনে একটি কমান্ড সহ একটি পঠনযোগ্য ফাইল রাখতে চান তবে আপনি এটিও ব্যবহার করতে পারেন:

my_command1 || exit $?
my_command2 || exit $?

এটি অবশ্য কোনও অতিরিক্ত ত্রুটি বার্তা প্রিন্ট করবে না। তবে কিছু ক্ষেত্রে ত্রুটিটি কোনওভাবেই ব্যর্থ কমান্ড দ্বারা মুদ্রণ করা হবে।


1
এটি হওয়ার কোনও কারণ নেই exit $?; কেবল তার ডিফল্ট মান হিসাবে exitব্যবহার করে $?
চার্লস ডাফি

পছন্দ করেছেন দুর্দান্ত, সুতরাং এটি আরও সহজ!
আলেক্সপিরিন

3

trapশেল builtin সংক্রামক সংকেত, এবং অন্যান্য প্রয়োজনীয় শর্ত, ব্যর্থ কমান্ড সঞ্চালনের (অর্থাত, একটি নন-জিরো রিটার্ন স্থিতি) সহ পারেন। সুতরাং আপনি যদি প্রতিটি একক কমান্ডের স্পষ্টরূপে রিটার্নের স্থিতি পরীক্ষা করতে না চান তবে আপনি বলতে পারেন trap "your shell code" ERRএবং কোনও আদেশ যখন কোনও শূন্য-শূন্য স্থিতি ফেরায় শেল কোডটি কার্যকর করা হবে। উদাহরণ স্বরূপ:

trap "echo script failed; exit 1" ERR

নোট করুন যে ব্যর্থ কমান্ডগুলি ধরার ক্ষেত্রে অন্যান্য ক্ষেত্রে যেমন পাইপলাইনগুলির বিশেষ চিকিত্সা প্রয়োজন; উপরেরটি ধরবে না false | true

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