बैश इक्विटी ऑपरेटर्स (==, -eq)


136

क्या कोई कृपया -eqऔर ==बैश स्क्रिप्टिंग में अंतर बता सकता है ?

निम्नलिखित में कोई अंतर है?

[ $a -eq $b ] तथा [ $a == $b ]

क्या यह केवल वह ==है जिसका उपयोग केवल तब किया जाता है जब चर संख्याएं होती हैं?

जवाबों:


187

यह दूसरा तरीका है: =और ==स्ट्रिंग तुलना के लिए हैं, -eqसंख्यात्मक के लिए है। -eqके रूप में एक ही परिवार में है -lt, -le, -gt, -ge, और -ne, अगर है कि आप याद है जो मदद करता है।

==बैश-इस्म है, वैसे। POSIX का उपयोग करना बेहतर है =। बैश में दो समान हैं, और सादे श =में काम करने की गारंटी केवल एक है।

$ a=foo
$ [ "$a" = foo ]; echo "$?"       # POSIX sh
0
$ [ "$a" == foo ]; echo "$?"      # bash specific
0
$ [ "$a" -eq foo ]; echo "$?"     # wrong
-bash: [: foo: integer expression expected
2

(साइड नोट: उन चर विस्तारों को उद्धृत करें! ऊपर दिए गए दोहरे उद्धरणों को न छोड़ें।)

यदि आप एक #!/bin/bashस्क्रिप्ट लिख रहे हैं तो मैं इसके बजाय उपयोग [[करने की सलाह देता हूं । दोगुने रूप में अधिक विशेषताएं हैं, अधिक प्राकृतिक सिंटैक्स, और कम गोच हैं जो आपको यात्रा करेंगे। दोहरे उद्धरण चिह्नों की आवश्यकता नहीं है $a, एक के लिए:

$ [[ $a == foo ]]; echo "$?"      # bash specific
0

यह सभी देखें:


1
@DJCrashdummy, [[एक पूरे के रूप में 1980 के दशक के ksh-ism है जो बैश (और कई अन्य गोले) को अपनाते हैं। यह पूरा बिंदु है - यदि आपके पास [[ बिल्कुल भी है , तो आप सुरक्षित रूप से मान सकते हैं कि इसके आसपास लागू सभी एक्सटेंशन ksh ( fnmatch()-स्टाइल पैटर्न मिलान, ERE के साथ नियमित अभिव्यक्ति =~और हां, स्ट्रिंग-बंटवारे का दमन और फाइलसिस्टम ग्लोबिंग) होगा उपलब्ध। चूँकि [[गैर-पोसिक्स सिंटैक्स अपनी संपूर्णता में है, इसलिए यह मानने में कोई अतिरिक्त पोर्टेबिलिटी हानि नहीं है कि यह जिन विशेषताओं के साथ पैदा हुआ था, वे उपलब्ध होंगे।
चार्ल्स डफी

1
@DJCrashdummy, ... आप जो लिंक दिखाते हैं, वह सही ढंग से बताता है कि उद्धरण कभी-कभी दाईं ओर की आवश्यकता होती है [[ $var = $pattern ]], अगर आप चाहते हैं कि अन्यथा एक fnmatch पैटर्न के रूप में इसके बजाय एक शाब्दिक स्ट्रिंग के रूप में व्याख्या की जाए। स्ट्रिंग fooकी कोई गैर-शाब्दिक व्याख्या नहीं है, जो उद्धरणों को पूरी तरह से सुरक्षित बनाती है; यह केवल तभी होता है जब ओपी मैच करना चाहता था, कहते हैं, foo*(शाब्दिक के रूप में तारांकन के साथ, उस स्ट्रिंग के बाद आने वाले कुछ भी अर्थ नहीं foo) जो उद्धरण या भागने की आवश्यकता होगी।
चार्ल्स डफी

@CharlesDuffy दुर्भाग्य से मुझे पता नहीं है कि आप किस बारे में बात कर रहे हैं, क्योंकि मेरी टिप्पणी को हटा दिया गया है और मुझे याद नहीं है क्योंकि यह काफी समय हो गया है। :-(
डीजे कर्कशम्मी

@DJCrashdummy, ... हुह, मैंने मान लिया कि आप इसे स्वयं वापस ले लेंगे। मूल रूप से, यह [[एक बेशवाद होने के अंदर अनियोजित विस्तार के बारे में आपत्ति थी (यह दर्शाता है कि एकमात्र कारण था जो आप उत्तर को +1 नहीं दे रहे थे)।
चार्ल्स डफी

@CharlesDuffy नहीं, यह एकमात्र कारण नहीं है: इस तथ्य के बगल में कि मुझे सरल कार्यों के लिए बैश-आईएमएस, केश-आईएमएस आदि पसंद नहीं है (यह सिर्फ परेशानी का कारण बनता है और शुरुआती को भ्रमित करता है), मुझे यह नहीं मिला कि एकल क्यों मिला ब्रेसिज़ [ ... ]और डबल बराबर चिह्न ==। : - /
डीजे कर्कशम्मी

27

यह ऑपरेटर के आसपास टेस्ट कंस्ट्रक्ट पर निर्भर करता है । आपके विकल्प डबल कोष्ठक, डबल ब्रेसेस, सिंगल ब्रेसेस या टेस्ट हैं

यदि आप ((...)) का उपयोग करते हैं, तो आप ==C के साथ अंकगणितीय इक्विटी का परीक्षण कर रहे हैं :

$ (( 1==1 )); echo $?
0
$ (( 1==2 )); echo $?
1

(नोट: 0साधन trueयूनिक्स भावना और गैर शून्य में एक असफल परीक्षण है)

का उपयोग करते हुए -eqडबल कोष्ठक के अंदर का एक वाक्यविन्यास त्रुटि है।

यदि आप [...] (या एकल ब्रेस) या [[...] (या डबल ब्रेस) का testउपयोग कर रहे हैं , या आप -eq, -ne, -lt, -le, -gt, या में से किसी एक का उपयोग कर सकते हैं -एक अंकगणितीय तुलना के रूप में

$ [ 1 -eq 1 ]; echo $?
0
$ [ 1 -eq 2 ]; echo $?
1
$ test 1 -eq 1; echo $?
0

==एकल या डबल ब्रेसिज़ (या के अंदर testआदेश) में से एक है स्ट्रिंग तुलना ऑपरेटरों :

$ [[ "abc" == "abc" ]]; echo $?
0
$ [[ "abc" == "ABC" ]]; echo $?
1

एक स्ट्रिंग ऑपरेटर के रूप में, व्हाट्सएप के =बराबर या उसके ==आस =- पास या ==इसकी आवश्यकता को नोट करता है।

जब आप कर सकते हैं [[ 1 == 1 ]]या [[ $(( 1+1 )) == 2 ]]यह स्ट्रिंग समानता का परीक्षण कर रहे हैं - अंकगणितीय समानता नहीं।

तो शायद-eq परिणाम की उम्मीद है कि पूर्णांक मान के बराबर है, भले ही आरएच एक स्ट्रिंग है और एक अनुगामी स्थान है:1+12

$ [[ $(( 1+1 )) -eq  "2 " ]]; echo $?
0

जबकि एक स्ट्रिंग की तुलना अनुगामी स्थान को चुनती है और इसके बाद स्ट्रिंग तुलना विफल हो जाती है:

$ [[ $(( 1+1 )) ==  "2 " ]]; echo $?
1

और एक गलत स्ट्रिंग तुलना पूर्ण गलत उत्तर का उत्पादन कर सकती है। '10' है कोषगत कम '2' की तुलना में है, तो एक स्ट्रिंग तुलना रिटर्न trueया 0। इस कीड़े द्वारा कई काटे गए हैं:

$ [[ 10 < 2 ]]; echo $?
0

10 के लिए सही परीक्षा बनाम अंकगणितीय रूप से 2 से कम होना:

$ [[ 10 -lt 2 ]]; echo $?
1

टिप्पणियों में, स्ट्रिंग्स पर पूर्णांक का उपयोग करने के तकनीकी कारण का एक प्रश्न है जो -eqस्ट्रिंग्स के लिए सही है जो समान नहीं हैं:

$ [[ "yes" -eq "no" ]]; echo $?
0

कारण यह है कि बैश अछूता है । आधार रूपांतरण सहित यदि संभव हो तो-eq स्ट्रिंग्स को पूर्णांकों के रूप में व्याख्यायित करने का कारण बनता है :

$ [[ "0x10" -eq 16 ]]; echo $?
0
$ [[ "010" -eq 8 ]]; echo $?
0
$ [[ "100" -eq 100 ]]; echo $?
0

और 0अगर बैश को लगता है कि यह सिर्फ एक स्ट्रिंग है:

$ [[ "yes" -eq 0 ]]; echo $?
0
$ [[ "yes" -eq 1 ]]; echo $?
1

तो [[ "yes" -eq "no" ]]के बराबर है[[ 0 -eq 0 ]]

अंतिम नोट: टेस्ट कंस्ट्रक्शंस के कई बैश स्पेसिफिक एक्सटेंशन POSIX नहीं हैं और इसलिए अन्य गोले में फेल हो जाएंगे। अन्य गोले आम तौर पर समर्थन नहीं करते हैं [[...]]और ((...))या==


मैं के बारे में उत्सुक हूँ तकनीकी कारण के लिए [[ "yes" -eq "no" ]]यह सच है लौटने। बश इन तार को पूर्णांक मानों के साथ कैसे किया जा सकता है जिनकी तुलना की जा सकती है? ;-)
ओडोनी

4
बैश चर अप्रकाशित होते हैं, इसलिए [[ "yes" -eq "no" ]]इसके बराबर [[ "yes" -eq 0 ]] या [[ "yes" -eq "any_noninteger_string" ]]- ऑल ट्रू है। -eqबलों तुलना पूर्णांक। "yes"एक पूर्णांक के रूप में व्याख्या की है 0; तुलना सही है अगर अन्य पूर्णांक 0या तो स्ट्रिंग परिणाम है 0
dawg

Boo, hiss re: ==कोड के नमूनों में (नॉनपोर्टेबल) दिखा रहा है और केवल =नीचे (पोर्टेबल, मानकीकृत) उल्लेख कर रहा है।
चार्ल्स डफी

24

==के लिए एक बैश-विशिष्ट उपनाम है =और यह एक संख्यात्मक तुलना के बजाय एक स्ट्रिंग (लेक्सिकल) तुलना करता है। eqपाठ्यक्रम की एक संख्यात्मक तुलना होने के नाते।

अंत में, मैं आमतौर पर फॉर्म का उपयोग करना पसंद करता हूं if [ "$a" == "$b" ]


15
==यहां उपयोग करना खराब रूप है, क्योंकि केवल =POSIX द्वारा निर्दिष्ट किया गया है।
चार्ल्स डफी

9
यदि आप वास्तव में उपयोग करने के लिए जोर देते हैं ==तो इसे बीच [[- बीच में लगाएं ]]। (और सुनिश्चित करें कि आपकी स्क्रिप्ट की पहली पंक्ति उपयोग करने के लिए निर्दिष्ट करती है/bin/bash ।)
होल्गेरो

18

दोस्तों: कई जवाब खतरनाक उदाहरण दिखाते हैं। ओपी का उदाहरण [ $a == $b ]विशेष रूप से निर्विवाद चर प्रतिस्थापन (अक्टूबर 17 के अनुसार) का उपयोग करता है। उसके [...]लिए स्ट्रिंग समानता के लिए सुरक्षित है।

लेकिन अगर आप विकल्पों की गणना करने जा रहे हैं [[...]], तो आपको यह भी सूचित करना होगा कि दाहिने हाथ को उद्धृत किया जाना चाहिए। यदि उद्धृत नहीं किया गया है, तो यह एक पैटर्न मैच है! (बैश मैन पेज से: "पैटर्न के किसी भी हिस्से को एक स्ट्रिंग के रूप में मिलान करने के लिए बाध्य करने के लिए उद्धृत किया जा सकता है।")।

यहाँ बैश में, "हाँ" वाले दो कथन पैटर्न मैचिंग हैं, अन्य तीन स्ट्रिंग समानता हैं:

$ rht="A*"
$ lft="AB"
$ [ $lft = $rht ] && echo yes
$ [ $lft == $rht ] && echo yes
$ [[ $lft = $rht ]] && echo yes
yes
$ [[ $lft == $rht ]] && echo yes
yes
$ [[ $lft == "$rht" ]] && echo yes
$

2
समानता के लिए भी विश्वसनीय होने [ "$lht" = "$rht" ] के लिए उद्धरण के साथ होना चाहिए। यदि आपके पास कोई फ़ाइल बनाई गई है touch 'Afoo -o AB', तो [ $lft = $rht ]वह सही हो जाएगी, भले ही वह फ़ाइल नाम बिल्कुल भी समान न हो AB
चार्ल्स डफी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.