ব্যাশ স্ক্রিপ্টে সেট-ই এর অর্থ কী?


713

আমি এই প্রিনস্ট ফাইলের বিষয়বস্তু অধ্যয়ন করছি যা স্ক্রিপ্টটি প্যাকেজটি ডেবিয়ান আর্কাইভ (.deb) ফাইল থেকে প্যাক করার আগেই সম্পাদন করে utes

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

#!/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

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

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

এটা ঠিক নাকি আমি কিছু মিস করছি?



46
আপনি গুগলে কেন এটি খুঁজে পেলেন না তার কারণ: -আপনার ক্যোয়ারিতে আমাদের অবহেলা হিসাবে ব্যাখ্যা করা হয়েছে। নিম্নলিখিত কোয়েরিটি ব্যবহার করে দেখুন: বাশ সেট "-e"
মালেভ

3
@ ট্যুটবার্গ যখন আমি নিজেই একই প্রশ্নটি জিজ্ঞাসা করেছি তখন আমি তাকিয়ে ছিলামman set
সেদাত কিলিংক

4
আপনি যদি এটি কীভাবে বন্ধ করতে চান তবে set +e
ড্যাশটি

@ ট্যুটবার্গ তবে সত্যিকারের লোকদের জিজ্ঞাসা করা কেবল রোবট থেকে অনুরোধ করার চেয়ে অনেক বেশি আকর্ষণীয় ;-)।
vdegenne

উত্তর:


797

থেকে help set:

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

তবে এটি কিছু লোকের দ্বারা খারাপ অনুশীলন হিসাবে বিবেচিত হয় (ব্যাশ এফএকিউ এবং আইআর ফ্রেইনোড # ব্যাশ এফএকিউ লেখক)। এটি ব্যবহার করার পরামর্শ দেওয়া হচ্ছে:

trap 'do_something' ERR

do_somethingত্রুটি দেখা দিলে ফাংশন চালাতে ।

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


14
"কমান্ড যদি শূন্য-স্থিতি স্থিতি দিয়ে বেরিয়ে যায় তবে অবিলম্বে প্রস্থান করুন" এর মতো একই শব্দার্থক চাইলে কি কি হবে?
সিএমসিডিগ্রাগনকাই

71
trap 'exit' ERR
চিপনার

12
ERRফাঁদ শেল ফাংশন দ্বারা উত্তরাধিকার সুত্রে প্রাপ্ত করা হয় না, তাই যদি আপনি ফাংশন আছে, set -o errtraceবা set -Eআপনি শুধু একবার ফাঁদ সেট করার অনুমতি এবং এটি বিশ্বব্যাপী প্রযোজ্য হবে।
ykay

31
নেই trap 'exit' ERRকি কিছু থেকে আলাদা set -e?
অ্যান্ডি

22
যদি এটি খারাপ অনুশীলন হয় তবে কেন এটি ডেবিয়ান প্যাকেজগুলিতে ব্যবহৃত হয় ?
ফুক্লভ

98

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


44
পাইপলাইনে শেষ কমান্ডটিতে ত্রুটি থাকলে এটি কেবল কার্যকর করা বন্ধ করে দেয় । একটি বাশ নির্দিষ্ট বিকল্প রয়েছে, set -o pipefailযা ত্রুটিগুলি প্রচার করতে ব্যবহার করা যেতে পারে যাতে পাইপলাইন কমান্ডের রিটার্ন মান শূন্য হয় না যদি পূর্ববর্তী কমান্ডগুলির মধ্যে একটি শূন্য-স্থিতি স্থিতি দিয়ে উপস্থিত হয়।
অ্যান্টনি জিওগিগান

2
মনে রাখবেন যে -o pipefailকেবলমাত্র পাইপলাইনের কমান্ডের প্রথম অ-শূন্যের (অর্থাত্ ভুল হওয়া ) কমান্ডের প্রস্থান স্থিতিটি-o errexit শেষ পর্যন্ত প্রচারিত। পাইপলাইনে বাকী কমান্ডগুলি এখনও চলছে , এমনকি set -o errexit। উদাহরণস্বরূপ: echo success | cat - <(echo piping); echo continues, যেখানে echo successএকটি সফল, কিন্তু ভ্রমপ্রবণ কমান্ড প্রতিনিধিত্ব করে, প্রিন্ট হবে success, pipingএবং continues, কিন্তু false | cat - <(echo piping); echo continues, সঙ্গে falseএখন কমান্ড প্রতিনিধিত্বমূলক চুপটি erroring, এখনও প্রিন্ট হবে pipingপ্রস্থান করার পূর্বে।
bb010g

54

অনুযায়ী ব্যাশ - দ্য সেট Builtin ম্যানুয়াল, যদি -e/ errexitসেট করা থাকে, শেল প্রস্থানের অবিলম্বে একটি পাইপলাইন একটি একক গঠিত সহজ কমান্ড , একটি তালিকা বা একটি যৌগ কমান্ড আয় একটি নন-জিরো স্ট্যাটাস।

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

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

আপনি যদি প্রস্থান করার সময় কিছু কার্যকর করতে চান, তবে সংজ্ঞা দেওয়ার চেষ্টা করুন trap:

trap onexit EXIT

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

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

অনুরূপ বিকল্প রয়েছে -E/errtrace যা এর পরিবর্তে ERR এ ফাঁদে যাবে, যেমন:

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

54

কোনও কারণে যে কোনও স্ক্রিপ্ট বাতিল হয়ে গিয়েছিল তার প্রস্থান স্থিতিটি কী তা নির্ধারণ করার সময় আমি এই পোস্টটি পেয়েছি 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

10

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

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

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

#!/bin/bash 
# set -e

lsd 

ls

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


এই উত্তরটি এমন কোনও অন্তর্দৃষ্টি বা তথ্য যুক্ত করে যা ইতিমধ্যে প্রশ্নে অন্যদের দেওয়া হয়নি?
চার্লস ডাফি

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

9

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

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

সাধারণ গ্যাটাচগুলি 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

সংক্ষিপ্ত

if something; then
    : nothing
else
    other
fi

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

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

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

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

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

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

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


এটি একটি দুর্দান্ত উত্তর। এবং এটি সেরা অনুশীলনকে উত্সাহ দেয়। জিআরইপি কমান্ড থেকে আমার ঠিক একই সমস্যা ছিল এবং আমি সত্যিই 'সেট-ই' সরাতে চাইনি
মিনি শি

7
Script 1: without setting -e
#!/bin/bash
decho "hi"
echo "hello"
This will throw error in decho and program continuous to next line

Script 2: With setting -e
#!/bin/bash
set -e
decho "hi" 
echo "hello"
# Up to decho "hi" shell will process and program exit, it will not proceed further
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.