কিভাবে একটি বিবৃতি ব্যবহার করে প্রস্থান স্থিতি পরীক্ষা করতে হবে


254

আমি ভাবছিলাম কোন নির্দিষ্ট আউটপুট প্রতিধ্বনি করতে যদি একটি বিবৃতিতে প্রস্থান স্থিতি পরীক্ষা করার সর্বোত্তম উপায় কী হবে?

আমি এটি থাকার কথা ভাবছি

if [ $? -eq 1 ]
then
   echo "blah blah blah"
fi

আমি যে সমস্যাটি করছি তা হ'ল প্রস্থান বিবৃতিটি if স্টেটমেন্টের আগে থাকে কারণ এটিতে এই প্রস্থান কোডটি থাকতে হবে। এছাড়াও, আমি জানি যে আমি কিছু ভুল করছি যেহেতু প্রস্থানটি অবশ্যই প্রোগ্রামটি থেকে বেরিয়ে আসবে।


3
পলিজ আপনার সম্পূর্ণ স্ক্রিপ্ট পোস্ট করে (বা কমপক্ষে একটি বিস্তৃত সুযোগ)। অন্যথায় এটি ঠিক আছে।
রেডএক্স

4
আপনার যদি দুটি নির্দিষ্ট জায়গায় কিছু নির্দিষ্ট প্রোগ্রামের আমন্ত্রণ থেকে প্রস্থান কোডটি ব্যবহার করতে হয়, তবে আপনাকে এটিকে সংরক্ষণ করতে হবেsome_program; rc=$?; if [ ${rc} -eq 1 ] .... fi ; exit ${rc}
twalberg এর

উত্তর:


261

চলমান প্রতিটি কমান্ডের একটি প্রস্থান স্থিতি রয়েছে।

এই চেকটি কমান্ডের প্রস্থান স্থিতির সন্ধান করছে যা সেই লাইনটি চালানোর আগে সম্প্রতি শেষ হয়েছিল।

আপনি যদি চান আপনার যখন যে পরীক্ষা ফেরৎ সত্য প্রস্থান স্ক্রিপ্ট (পূর্ববর্তী কমান্ড ব্যর্থ হয়েছে) তারপর আপনি করা exit 1যে ভিতরে (যাই হোক না কেন বা) ifপর ব্লক echo

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

if some_command; then
    echo command returned true
else
    echo command returned some error
fi

বা !প্রত্যাখ্যানের জন্য যে ব্যবহার ঘুরিয়ে

if ! some_command; then
    echo command returned some error
else
    echo command returned true
fi

নোট করুন যে ত্রুটি কোড কী তা তাদের কেউই পাত্তা দিচ্ছে না। আপনি যদি জানেন যে আপনি কেবলমাত্র একটি নির্দিষ্ট ত্রুটি কোডের বিষয়ে যত্নশীল হন তবে আপনাকে $?ম্যানুয়ালি পরীক্ষা করতে হবে ।


11
@ ডেডসেল 4 যখন কোনও প্রোগ্রামের ব্যর্থতায় শেল স্ক্রিপ্টটি বন্ধ করতে হবে, নিম্নলিখিত আইডিয়মটি দরকারীa_command || return 1
gboffi

10
@gboffi returnকেবল একটি ফাংশন এবং উত্সযুক্ত লিপিতে কাজ করে। আপনার যা দরকার তা exitঅন্যান্য ক্ষেত্রে জন্য (যা একটি sourced স্ক্রিপ্ট একটি ফাংশন মধ্যে খুব বেশী না)। তবে হ্যাঁ, এটি অবশ্যই একটি যুক্তিসঙ্গত প্যাটার্ন যদি আপনার কোনও নির্দিষ্ট ক্লিনআপ বা অতিরিক্ত আউটপুট না লাগে।
এটান রিজনার

1
আমাকে বলতে হবে যে dash, অনেকগুলি আধুনিক লিনাক্স বিতরণে ডিফল্ট নন-ইন্টারেক্টিভ শেল, মৃত্যুদন্ডপ্রাপ্ত শেল স্ক্রিপ্টগুলির মধ্যে returnএবং এর মধ্যে পার্থক্যটি বিবেচনা করে না exitdashআমি এতে ব্যবহার করলেও স্ক্রিপ্টটি প্রস্থান করে return
gboffi

শেষ দুটি চেক পিছনে যুক্তি কি? এটি পাল্টা স্বজ্ঞাত বলে মনে হচ্ছে যে if <command>প্রস্থান কোডটি 0 হলে শর্তটি পাস হয় অন্য কোনও ভাষায় এটি অন্যান্য উপায়ে হবে
sjw

3
গুরুত্বপূর্ণ দ্রষ্টব্য: এটি পাইপের জন্য কাজ করবে না। if ! some_command | some_other_commandকিছু_কমন্ডের স্থিতি উপেক্ষা করবে। দু'টি সর্বাধিক কমান্ড কর্মরূপগুলি হ'ল set -o pipefail(আপনার প্রোগ্রামের অন্যান্য অংশে কার্যকারিতা পরিবর্তন করতে পারে) বা ifবিবৃতিটিকে if [[ ${PIPESTATUS[0]} -ne 0 ]]পৃথক ফলো-আপ কমান্ড হিসাবে স্থানান্তরিত করা (কুরুচিপূর্ণ, তবে কার্যকরী)। আপনি যদি ব্যবহার করছেন set -eতবে আপনি || trueদ্বিতীয় সমাধানটি ব্যবহার করার সময় পাইপের শেষের দিকেও যুক্ত করতে চাইবেন যেহেতু প্রস্তাবিত নিয়ন্ত্রণ প্রবাহ থেকে পাইপটি সরিয়ে ফেলা ifঅন্যথায় তা অবিলম্বে প্রস্থান করতে পারে।
অ্যালেক্স জ্যানসেন

186

দ্রষ্টব্য যে প্রস্থান কোডগুলি! = 0 টি ত্রুটির প্রতিবেদন করতে ব্যবহৃত হয়। সুতরাং, এটি করা ভাল:

retVal=$?
if [ $retVal -ne 0 ]; then
    echo "Error"
fi
exit $retVal

পরিবর্তে

# will fail for error codes > 1
retVal=$?
if [ $retVal -eq 1 ]; then
    echo "Error"
fi
exit $retVal

আপনাকে অবশ্যই রেটওয়ালে পরীক্ষা করতে হবে, কারণ $? retVal এর অ্যাসাইনমেন্ট পরে আপনার কমান্ড থেকে ফেরত মান হয় না।
anr78

আসলেই নয়: mywiki.wooledge.org/BashFAQ/002 - তবে আমি সম্মত হই যে সম্পাদনা পাঠযোগ্যতার উন্নতি করে।
Oo.oO

1
শুধু এই পোস্টে ব্যাখ্যা করেছেন যে এটি পাওয়া stackoverflow.com/questions/20157938/...
anr78

dnf check-update0 (কোনও আপডেট নেই), 100 (আপডেট উপলব্ধ) বা 1 (ত্রুটি) প্রদান করে।
jww

1
@jww - ভাল, এটি কনভেনশন ( gnu.org/software/bash/manual/html_node/Exit-Status.html ) এর বিরুদ্ধে যাওয়ার পক্ষে ভাল ধারণা নয় । তবে, ভাল, এটি প্রতিরোধের কিছুই নেই। যদি dnfবিকাশকারীরা এইভাবে চয়ন করে থাকেন তবে এটি তাদের পছন্দ। তবে তবুও, তাদের পছন্দ স্পেসিফিকেশনটি ভাঙ্গা করে না :)
ওও.ওও

44

$?অন্য যে কোনও প্যারামিটার। শেষ পর্যন্ত কল করার আগে আপনি এর মানটি ব্যবহার করতে বাঁচাতে পারেন exit

exit_status=$?
if [ $exit_status -eq 1 ]; then
    echo "blah blah blah"
fi
exit $exit_status

29

সুস্পষ্ট ifবিবৃতি বিকল্প

ন্যূনতমরূপে:

test $? -eq 0 || echo "something bad happened"

সম্পূর্ণ:

EXITCODE=$?
test $EXITCODE -eq 0 && echo "something good happened" || echo "something bad happened"; 
exit $EXITCODE

13

কেবল সহায়ক এবং বিস্তারিত উত্তর যুক্ত করতে :

যদি আপনাকে প্রস্থান কোডটি স্পষ্টভাবে চেক করতে হয়, তবে এইভাবে গাণিতিক অপারেটরটি ব্যবহার করা ভাল (( ... )):

run_some_command
(($? != 0)) && { printf '%s\n' "Command exited with non-zero"; exit 1; }

অথবা, একটি caseবিবৃতি ব্যবহার করুন :

run_some_command; ec=$?  # grab the exit code into a variable so that it can
                         # be reused later, without the fear of being overwritten
case $ec in
    0) ;;
    1) printf '%s\n' "Command exited with non-zero"; exit 1;;
    *) do_something_else;;
esac

বাশে ত্রুটি পরিচালনা সম্পর্কে সম্পর্কিত উত্তর:

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