কোনও নির্দিষ্ট কমান্ডের জন্য ত্রুটি উপেক্ষা করে বাশ


444

আমি নিম্নলিখিত বিকল্পগুলি ব্যবহার করছি

set -o pipefail
set -e

ত্রুটিতে কার্যকর করা বন্ধ করতে বাশ স্ক্রিপ্টে। আমার কাছে স্ক্রিপ্ট নির্বাহের 100 ডলার রয়েছে এবং আমি স্ক্রিপ্টের প্রতিটি লাইনের রিটার্ন কোড চেক করতে চাই না।

তবে একটি বিশেষ কমান্ডের জন্য, আমি ত্রুটিটি উপেক্ষা করতে চাই। আমি এটা কিভাবে করবো?

উত্তর:


757

সমাধান:

particular_script || true

উদাহরণ:

$ cat /tmp/1.sh
particular_script()
{
    false
}

set -e

echo one
particular_script || true
echo two
particular_script
echo three

$ bash /tmp/1.sh
one
two

three কখনও মুদ্রিত হবে না।

এছাড়াও, আমি এটি যুক্ত করতে চাই যে যখন চালু pipefailহয় তখন শেলটির পক্ষে এটি যথেষ্ট মনে হয় যে পাইপটির কোনও কমান্ডের শূন্য-বহির্গমন কোড থাকে যখন পুরো পাইপটিতে নন-শূন্য প্রস্থান কোড থাকে ( pipefailএটি শেষের সাথে অবশ্যই শেষ হওয়া আবশ্যক) ।

$ set -o pipefail
$ false | true ; echo $?
1
$ set +o pipefail
$ false | true ; echo $?
0

15
+1 টি। যেমন বাশ রেফারেন্স ম্যানুয়াল ব্যাখ্যা করে , "শেলটি প্রস্থান করে না" যখন -eঅ্যাট্রিবিউট সেট করা হয় "যদি কমান্ডটি ব্যর্থ হয় তত্ক্ষণাত কোনও whileবা untilকীওয়ার্ড অনুসরণ করে কমান্ড তালিকার ifঅংশ হয়, কোনও বিবৃতিতে পরীক্ষার অংশ হয়, কোনও আদেশ কার্যকর করা হয় exec একটি &&বা ||তালিকায় চূড়ান্ত অনুসরণকারী কমান্ড ব্যতীত &&বা ||, পাইপলাইনে থাকা কোনও কমান্ড শেষ কিন্তু শেষ, অথবা যদি কমান্ডের ফেরতের স্থিতি উল্টানো হচ্ছে !। "
রুখ

@ ইগোরচুবিন আমি জানি না তবে এটি কাজ করে না কেন = আউটপুট (ldd $2/bin/* || true) | grep "not found" | wc -lব্যর্থ হওয়ার পরে এই লাইনের পরে স্ক্রিপ্টটি শেষ হচ্ছে
বিবেক গোয়েল

1
(ldd $2/bin/* || true) | grep "not found" | wc -l || true
ইগোর চুবিন

1
কারণ set -o pipefail। যখন grepকিছুই খুঁজে পাওয়া যায় না, এটি শূন্য-বহির্গমন প্রস্থান কোডটি ফেরত দেয় এবং শেলটির পক্ষে পুরো পাইপটিতে শূন্য-বহির্গমন কোড রয়েছে তা ভাবা যথেষ্ট।
ইগোর চুবিন

3
আপনি যদি রিটার্ন মান সংরক্ষণের বিকল্প চান (প্রস্থান ছাড়াই) তবে আপনি আমার মাইকম্যান্ড এবং & ট্রু ব্যবহার করে দেখুন। এটি আপনাকে পরবর্তী পদক্ষেপগুলিতে রিটার্ন কোডটি যাচাই করতে এবং প্রোগ্রামগতভাবে পরিচালনা করতে দেয়।
এড ওস্ট

179

|| trueআপনি যে আদেশটি ত্রুটি উপেক্ষা করতে চান তার পরে কেবল যুক্ত করুন ।


11
আমি মনে করি এটি যুক্ত করা জরুরী: এই পদ্ধতিটি প্রতিক্রিয়া কোড এবং ত্রুটির বার্তাটি অব্যাহত রাখতে দেয়, যেখানে "!" নীচে বর্ণিত পদ্ধতিটি প্রতিক্রিয়া কোড পরিবর্তন করবে এবং এইভাবে ত্রুটি উত্পন্ন করবে না। set -eত্রুটি বার্তাটি ব্যবহার এবং ক্যাপচার করার সময় এটি গুরুত্বপূর্ণ : উদাহরণস্বরূপset -e; TEST=$(foo 2>&1 || true); echo $TEST
স্প্যানকি

87

থামবেন না এবং প্রস্থান স্থিতিও সংরক্ষণ করুন

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

set -e
EXIT_CODE=0
command || EXIT_CODE=$?
echo $EXIT_CODE

2
আমার ঠিক
এটির

আমার জন্য কোনও কারণে কাজ করে না ... ওহ ভাল
জিফ

কমান্ডটি 0 ফেরত দিলে EXIT_CODE শূন্যে সেট করা হয় না যদিও শূন্য নয় বহির্গমন কোডগুলি ধরা পড়ে। কোন ধারণা কেন?
অঙ্কিতা 13

@ অঙ্কিতা 13 কারণ এটি যদি শূন্য হয় তবে প্রথমটি commandসফল হয়েছিল এবং তার পরে কী চালানো দরকার ||। এটি পড়ুন: যদি commandব্যর্থ হয় তবে করবেন EXIT_CODE=$?। আপনি সম্ভবত command || echo "$?"আরও ভার্বোজ ডিবাগিংয়ের জন্য "ট্র্যাপ" করতে বা ব্যবহার করতে পারেন। > - এই দেখুন stackoverflow.com/a/6110446/10737630
tinnick

63

আরও সংক্ষেপে:

! particular_script

থেকে POSIX স্পেসিফিকেশন সংক্রান্ত set -e(জোর খনি):

যখন এই বিকল্পটি চালু থাকে, শেল ত্রুটিগুলির ফলাফলগুলিতে তালিকাভুক্ত কোনও কারণে যদি একটি সাধারণ কমান্ড ব্যর্থ হয় বা একটি প্রস্থান স্থিতি মান> 0 প্রদান করে এবং কিছুক্ষণ পরে, বা কীওয়ার্ডের পরে যৌগিক তালিকার অংশ না হয় এবং কোনও AND বা OR তালিকার অংশ নয় এবং এটি পূর্ববর্তী পাইপলাইন নয় ! সংরক্ষিত শব্দ , তারপর শেল অবিলম্বে প্রস্থান করা হবে।


16
এটি কেবল একটি কমান্ডের প্রস্থান কোডকে উল্টে দেয়, সুতরাং সফলভাবে সমাপ্ত কমান্ড 0 এর পরিবর্তে 1 ফিরে আসবে এবং এর সাথে স্ক্রিপ্ট ব্যর্থ হবে -e
মারবনি

17
আমার বোধগম্যতা হল !শেলটি যেভাবেই হোক না কেন থেকে বেরিয়ে আসবে the এই স্ক্রিপ্টটি বার্তাটি প্রদর্শন Still alive!করি যখন আমি এটি চালাব, ইঙ্গিত করে যে স্ক্রিপ্টটি সমাপ্ত হয়েছে। আপনি কি বিভিন্ন আচরণ দেখছেন?
লিলি ফিনলে

7
আপনি ঠিক বলেছেন, এটি প্রস্থান স্থিতিটি উল্টে দেয়, তবে কমান্ড 0 বা 1 দিয়ে শেষ হয়ে গেলে স্ক্রিপ্ট ক্র্যাশ হয় না I আমি অমনোযোগী ছিলাম। যাইহোক, ডকুমেন্টেশনের উদ্ধৃতি দেওয়ার জন্য আপনাকে ধন্যবাদ, আমি আমার অভিব্যক্তিটি ifক্লজটিতে রেখে সমস্যার সমাধান করেছি।
মারবনি

42

"সত্য ফিরে" এর পরিবর্তে, আপনি এছাড়াও "noop" বা নাল ইউটিলিটি (উল্লেখ হিসাবে ব্যবহার করতে পারেন POSIX চশমা ) :এবং শুধু "কিছুই করতে"। আপনি কয়েকটি অক্ষর সংরক্ষণ করবেন। :)

#!/usr/bin/env bash
set -e
man nonexistentghing || :
echo "It's ok.."

3
যদিও ||: তেমন পরিষ্কার নয় || সত্য (যা অ বিশেষজ্ঞ বিশেষজ্ঞদের বিভ্রান্ত করতে পারে), আমি এটি সংকীর্ণতা পছন্দ করি
ডেভিড

এই রূপটি সিআই-তে গুরুত্বপূর্ণ হতে পারে এমন কোনও পাঠ্য ফেরত দেয় না।
কিভাগান্ট

5

আপনি যদি আপনার স্ক্রিপ্ট ব্যর্থতা প্রতিরোধ করতে চান এবং রিটার্ন কোডটি সংগ্রহ করুন:

command () {
    return 1  # or 0 for success
}

set -e

command && returncode=$? || returncode=$?
echo $returncode

returncode কমান্ড সফল হয় বা ব্যর্থ হয় তা বিবেচনা করেই সংগ্রহ করা হয়।


2

আমি সিএলআই সরঞ্জামগুলির সাথে কাজ করার সময় নীচে স্নিপেট ব্যবহার করছি এবং আমি জানতে চাই যে কিছু সংস্থান আছে কি না তবে আমি আউটপুটটির বিষয়ে চিন্তা করি না।

if [ -z "$(cat no_exist 2>&1 >/dev/null)" ]; then
    echo "none exist actually exist!"
fi

1
এটি সত্যিই চতুর্দিকে এবং মাঝারিভাবে ব্যয়বহুল উপায় বলে মনে হচ্ছেif [ -r not_exist ]
ট্রিপলি

1

আমি এই সমাধানটি পছন্দ করি:

: `particular_script`

পিছনের টিকগুলির মধ্যে কমান্ড / স্ক্রিপ্ট কার্যকর করা হয় এবং এর আউটপুট ":" কমান্ডকে দেওয়া হয় (যা "সত্য" এর সমতুল্য)

$ false
$ echo $?
1
$ : `false`
$ echo $?
0

সম্পাদনা: স্থির কুরুচিপূর্ণ টাইপ



0

এখান থেকে আমার জন্য কোনও সমাধান কাজ করেনি, সুতরাং আমি অন্য একটি খুঁজে পেয়েছি:

set +e
find "./csharp/Platform.$REPOSITORY_NAME/obj" -type f -iname "*.cs" -delete
find "./csharp/Platform.$REPOSITORY_NAME.Tests/obj" -type f -iname "*.cs" -delete
set -e

এটি সিআই এবং সিডির জন্য দরকারী। এইভাবে ত্রুটি বার্তাগুলি মুদ্রিত হয় তবে পুরো স্ক্রিপ্টটি চালানো চালিয়ে যায়।


0
output=$(*command* 2>&1) && exit_status=$? || exit_status=$?
echo $output
echo $exit_status

লগ ফাইল তৈরি করতে এটি ব্যবহারের উদাহরণ

log_event(){
timestamp=$(date '+%D %T') #mm/dd/yy HH:MM:SS
echo -e "($timestamp) $event" >> "$log_file"
}

output=$(*command* 2>&1) && exit_status=$? || exit_status=$?

if [ "$exit_status" = 0 ]
    then
        event="$output"
        log_event
    else
        event="ERROR $output"
        log_event
fi

0

উপরে থেকে সহজ সমাধানের জন্য ধন্যবাদ:

<particular_script/command> || true

নিম্নলিখিত ক্রিয়াকলাপ / স্ক্রিপ্ট পদক্ষেপগুলি এবং অতিরিক্ত প্রবাহ নিয়ন্ত্রণ বিকল্পগুলির সমস্যার সমাধানের জন্য ব্যবহার করা যেতে পারে:

if <particular_script/command>
then
   echo "<particular_script/command> is fine!"
else
   echo "<particular_script/command> failed!"
   #exit 1
fi

আমরা পরবর্তী ক্রিয়াগুলি ব্রেক করতে পারি এবং exit 1যদি প্রয়োজন হয়।

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