শর্তসাপেক্ষে কীভাবে কিছু করা যায় যদি কোনও আদেশ সফল হয় বা ব্যর্থ হয়


উত্তর:


358

শর্তসাপেক্ষে কীভাবে কিছু করা যায় যদি কোনও আদেশ সফল হয় বা ব্যর্থ হয়

বাশের ifবক্তব্য ঠিক এটাই করে:

if command ; then
    echo "Command succeeded"
else
    echo "Command failed"
fi

মন্তব্য থেকে তথ্য যোগ করার পদ্ধতি: আপনি না ব্যবহার করতে হবে [... ]এই ক্ষেত্রে সিনট্যাক্স। [নিজেই একটি কমান্ড, প্রায় সমতুল্য test। এটি সম্ভবত কোনও সর্বাধিক সাধারণ কমান্ড ifযা একটি শেল সিনট্যাক্সের অংশ বলে ধরে নেওয়া যেতে পারে which তবে আপনি যদি কোনও কমান্ড সফল হয়েছে কিনা তা পরীক্ষা করতে চান if, উপরের মতই কমান্ডটি সরাসরি ব্যবহার করুন ।

সম্পাদনা: স্পষ্টতার জন্য শীর্ষে প্রশ্নের উদ্ধৃতি (এই উত্তরটি পৃষ্ঠার শীর্ষের কাছে উপস্থিত হবে না)।


11
লক্ষ করুন যে সেমিকোলনটি গুরুত্বপূর্ণ।
থরবজর্ন রাভন অ্যান্ডারসন

21
অথবা আপনি কেবল thenএকটি পৃথক লাইনে লাগাতে পারেন ।
l0b0

36
@Joe: আমার মনে হয় আপনি কি বলতে চান if ! command ; then ... ; fi[এটি নিজেই একটি আদেশ, এবং এই ক্ষেত্রে এটির প্রয়োজন নেই।
কিথ থমসন

20
@ জো: আমার পথেও সঠিক হওয়ার গুণ রয়েছে। if [ ! command ]কার্যকর করা হয় না command; এটি commandএকটি স্ট্রিং হিসাবে আচরণ করে এবং এটি সত্য হিসাবে আচরণ করে কারণ এটির দৈর্ঘ্য অ-শূন্য রয়েছে। কমান্ডটির [প্রতিশব্দtest
কিথ থমসন

5
উফ। আপনি ঠিক বলেছেন।
জো

133

শেল কমান্ডটি যদি কাজ করে তবে আপনি যে ছোট ছোট জিনিসগুলি ঘটতে চান তা ব্যবহার করতে পারেন &&:

rm -rf somedir && trace_output "Removed the directory"

একইভাবে শেল কমান্ড ব্যর্থ হলে আপনি যে ছোট ছোট জিনিসগুলি করতে চান তা ব্যবহার করতে পারেন ||:

rm -rf somedir || exit_on_error "Failed to remove the directory"

অথবা উভয়

rm -rf somedir && trace_output "Removed the directory" || exit_on_error "Failed to remove the directory"

এই নির্মাণগুলির সাথে খুব বেশি কাজ করা বুদ্ধিমানের কাজ, তবে তারা উপলক্ষ্যে নিয়ন্ত্রণের প্রবাহকে আরও পরিষ্কার করে দিতে পারে।


3
এগুলি সংক্ষিপ্ত এবং কমপক্ষে কয়েকটি শেলের মধ্যে। আমি কেবল এই শর্তাধীন
নির্মাণগুলি

101

$?সর্বাধিক সাম্প্রতিক কমান্ড / ফাংশন কার্যকর করার ফলাফল ধারণ করে যার মানটি পরীক্ষা করুন :

#!/bin/bash

echo "this will work"
RESULT=$?
if [ $RESULT -eq 0 ]; then
  echo success
else
  echo failed
fi

if [ $RESULT == 0 ]; then
  echo success 2
else
  echo failed 2
fi

11
প্রযুক্তিগতভাবে সঠিক (এবং এইভাবে একটি ডাউনটোটের ওয়্যারেন্টি না দেওয়ার সময়), এটি বাশের ifমূর্তিটি ব্যবহার করছে না । আমি কিথ থম্পসনের উত্তর পছন্দ করি।
janmoesen

16
এই আইডিয়মের সুবিধাগুলি রয়েছে - এটি ফেরতের মান সংরক্ষণ করে। সব মিলিয়ে আমি এটিকে আরও শক্তিশালী বলে মনে করি, যদিও আরও ভার্বোস। এটি পড়া সহজ।
ট্যাক্সিলিয়ান

2
"বাশ যদি আইডিয়াম"?
এখনকার

3
@ নওকার এই সত্যটিই করেছেন যে এর একমাত্র উদ্দেশ্য ifএটি করা। বাশের প্রবাহ নিয়ন্ত্রণের পরিস্থিতি সমস্ত $?পর্দার আড়ালে পরীক্ষা করে; তারা কি না। সুস্পষ্টভাবে এর মান পরীক্ষা করা বেশিরভাগ ক্ষেত্রেই অপ্রয়োজনীয় হওয়া উচিত এবং এটি সাধারণত একটি শিক্ষানবিস এন্টিপ্যাটার্ন হয়।
ট্রিপলি

1
@ লুনাকিড যদি আপনি প্রস্থান কোডটির বিষয়ে চিন্তা না করেন if ! cmdতবে ভাল। অন্যথায়, একটি সাধারণ ব্যবস্থা হ'ল একটি elseধারা ব্যবহার করা । আপনার কোনও খালি থাকতে পারে না thenতবে আপনি কখনও কখনও দেখতে পাবেন then : nothing; elseযেখানে কোনও বিকল্প :নেই তা উল্লেখযোগ্য। trueপাশাপাশি কাজ করবে।
ট্রিপলি

47

এটি আমার পক্ষে কাজ করেছে:

command && echo "OK" || echo "NOK"

যদি commandসফল হয়, তবে echo "OK"মৃত্যুদন্ড কার্যকর করা হয় এবং এটি সফল হওয়ায় কার্যকরকরণ সেখানেই থেমে যায়। অন্যথায়, &&এড়ানো হয় এবং echo "NOK"কার্যকর করা হয়।


5
যদি আপনি কিছু করতে ব্যর্থ হন এবং প্রস্থান কোডটি সংরক্ষণ করতে চান (কমান্ড প্রম্পটে প্রদর্শন করতে বা স্ক্রিপ্টে পরীক্ষা করতে), আপনি এটি করতে পারেন: command && echo "OK" || c=$?; echo "NOK"; $(exit $c)
স্যাম হাসলার

2
@ স্যাম-হ্যাসলার: এমন হওয়া উচিত নয় command && echo "OK" || (c=$?; echo "NOK"; (exit $c))?
jrw32982

9
এছাড়াও, যদি echo "OK"অংশটি নিজেই ব্যর্থ হতে পারে তবে এটি আরও ভাল:command && (echo "OK"; exit 0) || (c=$?; echo "NOK"; (exit $c))
jrw32982

@ jrw32982, ভাল, আমি আগের নির্মাণগুলি ব্যবহার করেছি, তবে পরবর্তীটি নয়।
স্যাম হাসলার

আসল উত্তরটি মন্তব্যে রয়েছে, সবাইকে ধন্যবাদ!
জোশুয়া পিন্টার 20 ই

6

এটি লক্ষ করা উচিত যে if...then...fiএবং &&/ ||প্রকারের পদ্ধতির সাথে প্রস্থান স্থিতির সাথে সম্পর্কিত আদেশটি আমরা আদেশ দিয়ে ফিরে এসেছি (সাফল্যে 0); তবে, কমান্ড ব্যর্থ হলে বা ইনপুট নিয়ে কাজ করতে না পারলে কিছু কমান্ড একটি শূন্য-বহির্গমন স্থিতি ফিরিয়ে দেয় না। এর অর্থ হ'ল স্বাভাবিক ifএবং &&/ ||পদ্ধতিগুলি সেই নির্দিষ্ট কমান্ডগুলির জন্য কাজ করে না।

উদাহরণস্বরূপ, লিনাক্সে জিএনইউ file0 দিয়ে এখনও প্রস্থান করে যদি এটি কোনও অস্তিত্বযুক্ত ফাইলকে আর্গুমেন্ট হিসাবে গ্রহণ করে এবং findনির্দিষ্ট করা ফাইল ব্যবহারকারী সনাক্ত করতে না পারে।

$ find . -name "not_existing_file"                                          
$ echo $?
0
$ file ./not_existing_file                                                  
./not_existing_file: cannot open `./not_existing_file' (No such file or directory)
$ echo $?
0

এই ক্ষেত্রে, একটি সম্ভাব্য আমরা যেভাবে পরিস্থিতি হ্যান্ডেল পারে পড়া হয় stderr/ stdinবার্তা, যেমন ঐ যে দ্বারা ফিরে fileকমান্ড বা মত কমান্ডের আউটপুট পার্স find। যে উদ্দেশ্যে, caseবিবৃতি ব্যবহার করা যেতে পারে।

$ file ./doesntexist  | while IFS= read -r output; do                                                                                                                  
> case "$output" in 
> *"No such file or directory"*) printf "%s\n" "This will show up if failed";;
> *) printf "%s\n" "This will show up if succeeded" ;;
> esac
> done
This will show up if failed

$ find . -name "doesn'texist" | if ! read IFS= out; then echo "File not found"; fi                                                                                     
File not found

2

আমি সবচেয়ে ত্রুটিযুক্ত প্রবণতাটি নিয়ে আসতে পারি:

  • প্রথমে মানটি পাবেন। ধরুন আপনি এর মতো কিছু করেন:

RR=$?

এখন, শুধুমাত্র এই পরিস্থিতির জন্য নয়, আপনি অন্যদের মুখোমুখি হতে পারেন, বিবেচনা করুন:

সংজ্ঞাযুক্ত পরিবর্তনশীল:

$ AA=1 ; if (( "10#0${AA}" == 1 )) ; then echo yes ; else echo no ; fi

উত্তর: হ্যাঁ

$ AA=1 ; if (( "10#0${AA}" != 1 )) ; then echo yes ; else echo no ; fi

উত্তর: না

অনির্দিষ্ট পরিবর্তনশীল:

$ AA=1 ; if (( "10#0${BB}" == 1 )) ; then echo yes ; else echo no ; fi

উত্তর: না

$ AA=1 ; if (( "10#0${BB}" != 1 )) ; then echo yes ; else echo no ; fi

উত্তর: হ্যাঁ

$ AA=1 ; if (( "10#0${BB}" == 0 )) ; then echo yes ; else echo no ; fi

উত্তর: হ্যাঁ

এটি সমস্ত ধরণের ত্রুটিগুলি বন্ধ করে দেয়।

আপনি সম্ভবত সমস্ত সিনট্যাক্স সম্পর্কে সচেতন, তবে এখানে কয়েকটি টিপস:

  • উদ্ধৃতি ব্যবহার করুন। "blank"হতে একটি এড়ানো nothing
  • ভেরিয়েবলগুলির জন্য নতুন আধুনিক স্বরলিপিটি ${variable}
  • আপনার সংখ্যাটির আগে শূন্যকে যুক্ত করা "" কোনও সংখ্যা নয় "এড়ানোও।
  • তবে অপেক্ষা করুন, একটি শূন্য যুক্ত করা সংখ্যাটি পরিণত করে base-8। আপনি যেমন একটি ত্রুটি পাবেন:
    • value too great for base (error token is "08")উপরের সংখ্যা জন্য 7। এটি যখন 10#খেলতে আসে:
    • 10#সংখ্যা হতে বাধ্য করে base-10

1

তুমি এটি করতে পারো:

if ($( ping 4.4.4.4 -c1 > /dev/null )) ; then
  echo "ping response succsess!!!"
fi

9
এটি কাজ করে তবে দোষী হয় is আপনি একটি সাব-শেলের সাব-শেইলে পিং চালাচ্ছেন, pingকমান্ড হিসাবে চালানোর দৃষ্টিতে আউটপুট ক্যাপচার করা হয়েছে। তবে আউটপুটটি / dev / নালটিতে পুনঃনির্দেশিত হওয়ার কারণে এটি সর্বদা খালি স্ট্রিং হয়ে থাকবে। সুতরাং আপনি একটি সাব-শেলের কিছুই চালাচ্ছেন না, যার অর্থ পূর্ববর্তী প্রস্থান স্থিতি (কমান্ড সাবস্টিটিউশন সাবশেলের, যে পিংয়ের) বজায় থাকবে। স্পষ্টতই, সঠিক উপায়টি if ping ...; thenএখানে।
স্টাফেন চেজেলাস

1

এই থ্রেডে অন্য কোথাও উল্লিখিত হিসাবে, মূল প্রশ্নটি মূলত নিজের উত্তর দেয়। এখানে একটি চিত্র দেখানো হচ্ছে যে ifশর্তগুলিও বাসা বেধে থাকতে পারে।

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

#!/bin/bash

echo "Which error log are you checking today? "
read answer

if [ -f /opt/logs/$answer*.errors ]
    then
        if [ -s /opt/logs/$answer*.errors ]
            then
                echo "Content is present in the $answer error log file."
            else
                echo "No errors are present in the $answer error log file."
        fi
    else
        echo "$answer does not have an error log at this time."
fi

2
আপনার উত্তরটি সেটাই করে, তবে আপনার উত্তরটি প্রশ্নটির কোনও উত্তর দেয় না।
জেফ শ্যাচলার

@ জেফ শ্যাচলার, আপনার নোটের জন্য আপনাকে ধন্যবাদ। প্রশ্নের উত্তর উল্লেখ করার জন্য আমি আমার পোস্টটি সম্পাদনা করেছি।
কোয়ার্টজিনকোয়ার্টজ

1
#!/bin/bash

if command-1 ; then
   echo "command-1 succeeded and now running from this block command-2"
   command-2
else
   echo "command-1 failed and now running from this block command-3"
   command-3
fi

3
এটি বিদ্যমান স্বীকৃত উত্তরের মতো দেখতে বেশ কিছুটা ; দয়া করে বৈশিষ্ট্যাবলী কাজ পুনঃব্যবহার করছি, অথবা আপনার উত্তর আপনার নিজের প্রচেষ্টা যোগ করুন।
জেফ শ্যাচলার

-3

এটি কেবল এইভাবে করা যেতে পারে কারণ $?আপনাকে মৃত্যুদন্ড কার্যকর করা শেষ কমান্ডের স্থিতি দেয়।

সুতরাং এটি হতে পারে

#!/bin/sh

... some command ...

if [ $? == 0 ] ; then
  echo '<the output message you want to display>'
else 
  echo '<failure message>'
fi

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