linux একটি bash স্ক্রিপ্ট সেট-ই অর্থ কি?




shell (5)

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

এই পরীক্ষা করতে, কেবল একটি bash প্রম্পটে set -e টাইপ করুন। এখন, ls চলমান চেষ্টা করুন। আপনি একটি ডিরেক্টরি তালিকা পাবেন। এখন, lsd টাইপ lsd । যে কমান্ডটি স্বীকৃত নয় এবং একটি ত্রুটি কোড ফেরত দেবে, এবং তাই আপনার ব্যাশ প্রম্পট বন্ধ হবে ( set -e কারণে)।

এখন, একটি 'স্ক্রিপ্ট' প্রসঙ্গে এটি বুঝতে, এই সহজ স্ক্রিপ্টটি ব্যবহার করুন:

#!/bin/bash 
# set -e

lsd 

ls

আপনি যদি এটি চালান, তবে আপনি শেষ লাইনে ls থেকে ডিরেক্টরি তালিকা পাবেন। আপনি যদি set -e lsd আবার সংশোধন করেন এবং আবার চালান করেন, তবে lsd থেকে ত্রুটির মুখোমুখি হওয়ার পরে আপনি bash স্টপ প্রক্রিয়া হিসাবে ডিরেক্টরি তালিকাটি দেখতে পাবেন না।

আমি এই প্রিনস্ট ফাইলের বিষয়বস্তু অধ্যয়ন করছি যে স্ক্রিপ্টটি তার ডেবিয়ান সংরক্ষণাগার (.deb) ফাইল থেকে অপঠিত হওয়ার পূর্বে চালিত হয়

স্ক্রিপ্ট নিম্নলিখিত কোড আছে:

#!/bin/bash
set -e
# Automatically added by dh_installinit
if [ "$1" = install ]; then
   if [ -d /usr/share/MyApplicationName ]; then
     echo "MyApplicationName is just installed"
     return 1
   fi
   rm -Rf $HOME/.config/nautilus-actions/nautilus-actions.conf
   rm -Rf $HOME/.local/share/file-manager/actions/*
fi
# End automatically added section

আমার প্রথম প্রশ্নটি লাইন সম্পর্কে:

set -e

আমার মনে হয় বাকি স্ক্রিপ্টটি বেশ সহজ: ডেবিয়ান / উবুন্টু প্যাকেজ ম্যানেজার একটি ইনস্টলেশানটি চালনা করছে কিনা তা যাচাই করে। যদি এটি হয়, এটি আমার অ্যাপ্লিকেশনটি সিস্টেমে ইনস্টল করা হয়েছে কিনা তা পরীক্ষা করে। যদি এটি থাকে, তাহলে স্ক্রিপ্টটি "আমার অ্যাপ্লিকেশন নামটি ইনস্টল করা হয়েছে" বার্তাটি প্রিন্ট করে এবং শেষ হয় ( return 1 অর্থ যা "ত্রুটির" সাথে শেষ হয়, তাই না?)।

যদি ব্যবহারকারী আমার প্যাকেজটি ইনস্টল করতে ডেবিয়ান / উবুন্টু প্যাকেজ সিস্টেমটি জিজ্ঞাসা করে তবে স্ক্রিপ্টটি দুটি ডিরেক্টরি মুছে ফেলে।

এই অধিকার বা আমি কিছু অনুপস্থিত?


বাশ - সেট errexit ম্যানুয়াল, if -e / errexit সেট করা থাকে, pipeline একটি সহজ কমান্ড থাকা থাকলে শেলটি তাত্ক্ষণিকভাবে ছেড়ে যায়, একটি তালিকা বা যৌগ কমান্ডটি একটি অ-শূন্য স্থিতি প্রদান করে।

ডিফল্টরূপে, পাইপলাইনের প্রস্থান স্থিতি পাইপলাইনের শেষ কমান্ডের প্রস্থান স্থিতি হয়, যতক্ষণ না pipefail বিকল্প সক্ষম থাকে (এটি ডিফল্টভাবে অক্ষম থাকে)।

যদি তাই হয়, একটি অ-শূন্য স্থিতি সহ প্রস্থান করার জন্য শেষ (ডানদিকে) কমান্ডের পাইপলাইনের প্রত্যাবর্তন অবস্থা, অথবা সমস্ত কমান্ড সফলভাবে প্রস্থান হলে।

আপনি যদি প্রস্থান করার জন্য কিছু চালাতে চান তবে trap সংজ্ঞায়িত করার চেষ্টা করুন, উদাহরণস্বরূপ:

trap onexit EXIT

যেখানে onexit আপনার ফাংশনটি প্রস্থান করে কিছু করার জন্য, নীচের মতো যা সহজ স্ট্যাক ট্রেস মুদ্রণ করছে:

onexit(){ while caller $((n++)); do :; done; }

একই রকম বিকল্প -E/errtrace যা পরিবর্তে ইআরআর এ ফাঁদে ফেলবে, যেমন:

trap onerr ERR

উদাহরণ

জিরো স্ট্যাটাস উদাহরণ:

$ true; echo $?
0

অ-শূন্য অবস্থা উদাহরণ:

$ false; echo $?
1

নেতিবাচক অবস্থা উদাহরণ:

$ ! false; echo $?
0
$ false || true; echo $?
0

pipefail সাথে পরীক্ষা নিষ্ক্রিয় করা হচ্ছে:

$ bash -c 'set +o pipefail -e; true | true | true; echo success'; echo $?
success
0
$ bash -c 'set +o pipefail -e; false | false | true; echo success'; echo $?
success
0
$ bash -c 'set +o pipefail -e; true | true | false; echo success'; echo $?
1

pipefail দিয়ে পরীক্ষা সক্ষম করা হচ্ছে:

$ bash -c 'set -o pipefail -e; true | false | true; echo success'; echo $?
1

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

উদাহরণস্বরূপ, ধরুন আমার একটি শেল স্ক্রিপ্ট outer-test.sh :

#!/bin/sh
set -e
./inner-test.sh
exit 62;

inner-test.sh জন্য কোড হল:

#!/bin/sh
exit 26;

যখন আমি কমান্ড লাইন থেকে outer-script.sh আমার বাইরের স্ক্রিপ্ট অভ্যন্তরীণ স্ক্রিপ্টের প্রস্থান কোডটি বন্ধ করে দেয়:

$ ./outer-test.sh
$ echo $?
26

help set থেকে:

  -e  Exit immediately if a command exits with a non-zero status.

তবে এটি কিছু লোকের দ্বারা খারাপ অভ্যাস বলে মনে করা হয় (bash FAQ এবং IRC freenode #bash এ এই FAQ লিখেছেন) এটি আরও ভাল ব্যবহার বলে:

trap 'do_something' ERR

ত্রুটি ঘটে যখন do_something ফাংশন চালানোর জন্য।

http://mywiki.wooledge.org/BashFAQ/105 দেখুন


এটি একটি পুরনো প্রশ্ন, কিন্তু এখানে কোনও উত্তর ডেবিয়ান প্যাকেজ হ্যান্ডলিং স্ক্রিপ্টগুলিতে set -o errexit উর set -o errexit set -e set -o errexit ব্যবহার সম্পর্কে আলোচনা করে। এই স্ক্রিপ্টগুলিতে এই বিকল্পটির ব্যবহার বাধ্যতামূলক , ডেবিয়ান নীতি অনুসারে; অভিপ্রায় একটি unhandled ত্রুটি অবস্থা কোনো সম্ভাবনা এড়াতে দৃশ্যত হয়।

অভ্যাসের অর্থ এই যে, আপনি কোন কমান্ডগুলি চালাচ্ছেন তা কোনও ত্রুটি ফেরত দিতে পারে এবং সেগুলির মধ্যে প্রতিটি ত্রুটিগুলি স্পষ্টভাবে পরিচালনা করতে পারে এমন শর্তগুলির অধীনে আপনাকে বুঝতে হবে।

Common Gotchas উদাহরণস্বরূপ diff (একটি diff একটি ত্রুটি প্রদান করে) এবং grep (কোন মিল নেই এমন একটি ত্রুটি প্রদান করে)। আপনি সুস্পষ্ট হ্যান্ডলিংয়ের ত্রুটিগুলি এড়াতে পারেন:

diff this that ||
  echo "$0: there was a difference" >&2
grep cat food ||
  echo "$0: no cat in the food" >&2

(বার্তাটিতে বর্তমান স্ক্রিপ্টের নামটি অন্তর্ভুক্ত করার জন্য এবং স্ট্যান্ডার্ড আউটপুট পরিবর্তে মানক ত্রুটির জন্য ডায়াগনস্টিক বার্তাগুলি লেখার জন্য আমরা কীভাবে যত্ন নিই তাও লক্ষ্য করুন।)

যদি কোন স্পষ্ট হ্যান্ডলিং সত্যিই প্রয়োজনীয় বা দরকারী হয়, স্পষ্টভাবে কিছুই না:

diff this that || true
grep cat food || :

(শেলের ব্যবহার : নন-অপ কমান্ডটি সামান্য অস্পষ্ট, তবে মোটামুটি সাধারণভাবে দেখা যায়।)

শুধু পুনরাবৃত্তি,

something || other

জন্য shorthand হয়

if something; then
    : nothing
else
    other
fi

অর্থাত্ আমরা স্পষ্টতই বলি other চালানো উচিত যদি something ব্যর্থ হয়। লংহ্যান্ড if (এবং অন্যান্য শেল ফ্লো কন্ট্রোল বিবৃতি until ) একটি ত্রুটি পরিচালনা করার জন্যও বৈধ উপায় (প্রকৃতপক্ষে, যদি এটি না থাকে তবে set -e সহ শেল স্ক্রিপ্টগুলিতে প্রবাহ নিয়ন্ত্রণ বিবৃতি থাকতে পারে না!)

এবং এটির মতো, হ্যান্ডলারের অনুপস্থিতিতে শুধুমাত্র স্পষ্ট হওয়া উচিত, set -e যদি সম্পূর্ণ diff খুঁজে পায় তবে সম্পূর্ণ স্ক্রিপ্টটি ত্রুটিযুক্তভাবে অবিলম্বে ব্যর্থ হতে পারে, অথবা যদি grep কোনও মিল খুঁজে পায় না।

অন্য দিকে, কিছু কমান্ড আপনি তাদের চাইলে একটি ত্রুটি প্রস্থান অবস্থা তৈরি করবেন না। সাধারণভাবে সমস্যাযুক্ত কমান্ড find পাওয়া যায় (ফাইলগুলি প্রকৃতপক্ষে পাওয়া যায় কিনা তা প্রস্থান স্থিতিটি দেখায় না) এবং sed (স্ক্রিপ্টটি কোনও ইনপুট পেয়েছে কিনা বা প্রস্থান সফলভাবে কোন কমান্ড সম্পাদন করবে না তা প্রস্থান করে। কিছু পরিস্থিতিতে একটি সহজ গার্ড একটি কমান্ডের পাইপ যা কোন আউটপুট নেই যদি চিৎকার করে থাকে:

find things | grep .
sed -e 's/o/me/' stuff | grep ^

এটি লক্ষ্য করা উচিত যে পাইপলাইনের প্রস্থান অবস্থাটি সেই পাইপলাইনে শেষ কমান্ডের প্রস্থান অবস্থা। সুতরাং উপরের কমান্ডগুলি সম্পূর্ণরূপে সম্পূর্ণরূপে find এবং sed অবস্থা sed এবং শুধুমাত্র grep অবশেষে সফল হয়েছে কিনা তা আপনাকে বলে।

(অবশ্যই, ব্যাশ অবশ্যই set -o pipefail তবে ডেবিয়ান প্যাকেজ স্ক্রিপ্টগুলি বাশ বৈশিষ্ট্যগুলি ব্যবহার করতে পারে না। নীতিগুলি এই স্ক্রিপ্টগুলির জন্য POSIX sh ব্যবহারটি দৃঢ়ভাবে নির্দেশ করে, যদিও এটি সর্বদা ছিল না।)

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





sh