[[]] परीक्षण में दोहरे उद्धरण चिह्नों का उपयोग क्यों करें?


23

मान लीजिए कि हमारे पास एक bash स्क्रिप्ट में 2 पूर्णांक हैं:

value1=5
value2=3

फिर हमें परीक्षण के मामले में दोहरे उद्धरण चिह्नों का उपयोग करने की आवश्यकता क्यों है? उदाहरण के लिए:

if [[ "$value1" -eq "$value2" ]]

सिर्फ निम्नलिखित का उपयोग क्यों नहीं करते?

if [[ $value1 -eq $value2 ]]

मेरे लिए, दोहरे उद्धरणों का कोई मतलब नहीं है।


5
शेल में उद्धृत करना स्ट्रिंग्स के साथ बहुत कम है (जैसा कि डेटा प्रकारों में।) यह वास्तव में शेल को शब्द विभाजन (और अन्य प्रकार के विस्तार) करने से रोकने के बारे में है।
filbranden

13
हालांकि, जैसा कि टेर्डन ने बताया, यह आवश्यक नहीं है कि इस विशिष्ट निर्माण में चर भी (और, निश्चित रूप से, एक शब्द-शब्द-मान के साथ कहीं भी) हो, मैं हमेशा आपकी चर को उद्धृत करने की सलाह देना चाहूंगा क्या आप वास्तव में विच संदर्भों में जानते हैं कि आप चरों को बिना पढ़े छोड़ सकते हैं? सभी पर उद्धृत करने का कारण, भले ही यह आवश्यक नहीं है 5और 3, रखरखाव है। मान बाद में बदल सकते हैं, और परिणामी त्रुटियां स्पष्ट नहीं हो सकती हैं।
पीटर - मोनिका

2
@sudodus मुझे नहीं लगता कि यह [[ ]]केवल के लिए सच है [ ]
बेंजामिन डब्ल्यू।

1
आप सही हैं, @BenjaminW शब्द विभाजन केवल एकमात्र मामला नहीं है कि चर के लिए दोहरे उद्धरण चिह्नों का उपयोग करना एक अच्छा विचार क्यों है। एक चर के खाली होने पर भी ऐसा होता है। यह कथन को [] विफल कर देगा (उदाहरण के लिए [2 -eq] एक त्रुटि के साथ, लेकिन [[]] असुरक्षित नहीं है (शब्द बंटवारे के मामले के समान)।
sudodus

2
@marcelm, Bash, ksh और Zsh के पूर्णांक चर हैं, और [[ ]]उनके भीतर भी पूर्णांकों के परिचालकों को मिलाते -eqहैं।
ilkachachu

जवाबों:


7

शब्द विभाजन।

यह उदाहरण बहुत ही असंभव है, लेकिन संभव है , इसलिए यदि आप रक्षात्मक रूप से कोड करना चाहते हैं, तो अपने ट्रैक को उद्धरण के साथ कवर करें:

$ set -x
$ value1=5
+ value1=5
$ value2=3
+ value2=3
$ [ $value1 -eq $value2 ]
+ '[' 5 -eq 3 ']'

ठीक है, अब तक के सभी अच्छे। चलो रिंच को गियर में फेंक दें:

$ IFS=456
+ IFS=456
$ [ $value1 -eq $value2 ]
+ '[' '' -eq 3 ']'
bash: [: : integer expression expected

उफ़।

$ [ "$value1" -eq "$value2" ]
+ '[' 5 -eq 3 ']'

आह।


2
लेकिन ओपी डबल ब्रैकेट का उपयोग करता है, इसलिए कोई शब्द विभाजन नहीं होता है।
user000001

5
हां, यह वास्तव में बैश के [[ ]]निर्माण के लिए प्रासंगिक नहीं है ।
terdon

1
एह? [ $value1 -eq $value2 ]एक खाली के साथ बाईं ओर नहीं के साथ value1होगा । '[' -eq 3 ']'''
चार्ल्स डफी

मैं भी हैरान था, लेकिन इसके सबूत हैं।
ग्लेन जैकमैन

1
यह उत्तर सीधे प्रश्न से संबंधित नहीं है । मुझे आश्चर्य है कि इसे स्वीकार कर लिया गया। सामुदायिक विकि के रूप में स्थापित करना।
ग्लेन जैकमैन

35

आपको वास्तव में यहां उद्धरणों की आवश्यकता नहीं है। यह बहुत कम मामलों में से एक है जहां एक चर का उपयोग करना सुरक्षित है। आप इसकी पुष्टि कर सकते हैं set -x:

$ var1=""
$ var2="3"
$ set -x
$ if [[ $var1 -eq $var2 ]]; then echo "match!"; else echo "no match!"; fi
+ [[ '' -eq 3 ]]
+ echo 'no match!'
no match!
$ if [[ "$var1" -eq "$var2" ]]; then echo "match!"; else echo "no match!"; fi
+ [[ '' -eq 3 ]]
+ echo 'no match!'
no match!

जैसा कि आप ऊपर देख सकते हैं, परीक्षण के उद्धृत और अयोग्य संस्करण बैश द्वारा सटीक एक ही चीज़ के लिए हल किए गए हैं। उसी के लिए सच होना चाहिए zshऔर, मुझे लगता है, कोई अन्य शेल जो [[ ]]ऑपरेटर का समर्थन करता है ।

ध्यान दें कि यह अधिक पोर्टेबल के साथ ऐसा नहीं है [ ]:

$ if [ $var1 -eq $var2 ]; then echo "match!"; else echo "no match!"; fi
+ '[' -eq 3 ']'
sh: [: -eq: unary operator expected
+ echo 'no match!'
no match!

[ ]निर्माण, के विपरीत [[ ]]एक, के हवाले से की आवश्यकता है।


कब और क्यों उद्धृत करना आवश्यक है, इसके बारे में अधिक जानने के लिए कुछ उपयोगी लिंक:


पूर्णांक चर के साथ इस मामले में उन्हें इस तरह से घोषित करना बेहतर होगा। declare -i var1=है 0जब मूल्यांकन किया।
फ्रेडी

4
ध्यान दें कि -eqहै अंकगणित तुलना है, तो आप भी छोड़ सकते हैं $बाहर (में [[ .. ]]), और लिखने [[ a -eq b ]]। स्ट्रिंग तुलना के साथ, आपको $निश्चित रूप से आवश्यक है, इसलिए[[ $a = $b ]]
ilkkachu

2
@ user000001 अच्छी बात है। हालांकि, निश्चित रूप से, यह बहुत संभव है कि आप उन लोगों को विस्तारित करना चाहते हैं। उदाहरण के लिए, मुझे उम्मीद है कि यह एक मैच होगा var1="afoob"; var2="a*b"; [[ $var1 = $var2 ]] && echo match:। यदि आप एक ग्लोब के रूप में उनके अभिनय के बिना ग्लोब पात्रों का उपयोग करना चाहते हैं (जैसे कि [[ ]]) तो आपको उद्धृत करने की आवश्यकता है, हाँ।
terdon

3
@ilkachu, कि मुझे आश्चर्य। मैंने सोचा था कि "नंगे" चर को केवल एक सरणी सबस्क्रिप्ट या ((...))या के भीतर माना जाएगा $((...)। यह काम करने के लिए प्रकट होता है, लेकिन (पुराने क्रोधी आदमी, सक्षम) मुझे यह पसंद नहीं है।
ग्लेन जैकमैन

1
@glennjackman, ठीक है, खेद है कि आपको यह बताने के लिए एक है, लेकिन हाँ, -eqअंदर और दोस्तों के [[ ]]लिए अंकगणितीय संदर्भ भी हैं। :) (संबंधित: बैश के अंदर स्वचालित चर विस्तार [[]] कमांड )
ilkkachu

17

भले ही दोहरे उद्धरण चिह्नों की आवश्यकता न हो, लेकिन उनका उपयोग करने के कारण हैं:

  • अच्छा अभ्यास / आदत: इस मामले में वे आवश्यक नहीं हैं, लेकिन सामान्य रूप से दोहरे उद्धरणों में अनपेक्षित शब्द विभाजन से बचना है।
  • क्योंकि value1और value2परिवर्तनशील हैं, और आप नहीं जानते कि उनमें क्या है। अन्यथा आप यह भी पूछ सकते हैं, "चेकिंग के बजाय चरों के साथ परेशान क्यों if [[ 5 -eq 3 ]]? या इसे और आगे ले जाना, क्यों परेशान करना ifजब आप पहले से ही जानते हैं कि 5 3 के बराबर नहीं है? अक्सर रक्षात्मक होना बेहतर होता है! यह सच है।" वह शब्द-विभाजन नहीं होगा [[, लेकिन ऐसे मामले जहां शब्द-विभाजन नहीं होता है, दुर्लभ हैं। फिर से, पहले बिंदु को देखें।)

1

सीधे आपके प्रश्न से संबंधित नहीं, लेकिन मैं उपयोग करता हूं

यदि (($ value1 == $ value2)); फिर

जब मैं संख्याओं की तुलना करता हूं, लेकिन वहां भी आपको उद्धरण का उपयोग करने की आवश्यकता नहीं है।


2
if (( value1 == value2 )); then। अंकगणितीय संदर्भों में, आपको इसकी आवश्यकता भी नहीं है $। यह प्रश्न, हालांकि, [[ ... ]]परीक्षणों के भीतर उपयोग किए जाने वाले चर पर ध्यान केंद्रित करता है ।
Kusalananda

1
मुझे पता है। लेकिन मैं स्पष्ट रूप से इस सुविधा का उपयोग नहीं करता हूं क्योंकि मैं चाहता हूं कि मेरे चर नाम सुसंगत हों और इस प्रकार हर समय उपसर्ग के रूप में $ का उपयोग करें।
framp

1

तुम पूरी तरह ठीक हो!

दोहरे वर्ग कोष्ठक के भीतर उद्धृत करने का कोई मतलब नहीं है, कम से कम इस मामले में।

लेकिन चूंकि मैं प्रतिदिन दोहरे उद्धरणों का उपयोग करता हूं - विशेष रूप से एकल वर्ग ब्रैकेट अभिव्यक्तियों के लिए, कार्यों और लिपियों के लिए तर्क पारित करने के साथ-साथ चर असाइनमेंट कभी-कभी (जो सरल विलंब के लिए पूरी तरह से बेकार है) - मुझे लगता है कि कुछ लोग, कम से कम मैं करते हैं, सहज रूप से चर विस्तार के आसपास दोहरे उद्धरण लिखें

दोहरा उद्धरण आपको बचत की भावना दे सकता है। यह घर आने जैसा है जहां दोहरे भाव हैं। - डी। कुम्मर

परिणामी रूप से और समझदारी से दोहरे उद्धरण-चिह्नों को करने का एक लाभ - लेकिन जैसा कि यह समझ में आता है - यह है कि सहकर्मी जो बैश करने के लिए नए हैं, वे सीख सकते हैं कि कैसे अधिक स्थिर स्क्रिप्ट लिखना है । यह इस तथ्य को भी स्पष्ट करता है कि बैश के साथ डेटा प्रोसेसिंग की कला क्षेत्र विभाजकों द्वारा डेटा धाराओं (चर सहित) को अलग करने और फिल्टर के माध्यम से उन्हें पाइप करने के बारे में अधिक है । जैसे ही आप अपने डेटा हिस्सा खंड से अलग हो गए, उन्हें दोहरे उद्धरण चिह्नों के साथ पकड़ लें!

एक अन्य लाभ एक कोड हाइलाइटिंग संपादक के भीतर डबल उद्धृत स्ट्रिंग्स के साथ बैश स्क्रिप्ट की बेहतर पठनीयता हो सकती है ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.