चलो, expr और $ [के बीच अंतर


23

मैं जानना चाहता हूं कि वास्तव में क्या अंतर है

a=$[1+1]
a=$((1+1))
let a=1+1
a=$(expr 1 + 1 )

सभी 4 चर को 2 के साथ असाइन करते हैं, लेकिन क्या अंतर है?

अब तक मुझे जो पता चला है, वह यह है कि एक्सप्र धीमी है क्योंकि यह वास्तविक शेल बिलिन नहीं है। लेकिन इससे ज्यादा कुछ नहीं।

जवाबों:


25

ये सभी अंकगणित से संबंधित हैं, लेकिन अलग-अलग तरीकों से और चर अलग-अलग तरीकों से बनाए जाते हैं। इनमें से कुछ bashगोले के लिए विशिष्ट हैं , जबकि अन्य नहीं हैं।

  • $((...))को अंकगणितीय विस्तार कहा जाता है , जो कि विशिष्ट bashऔर kshगोले है। यह सरल पूर्णांक अंकगणित करने की अनुमति देता है , हालांकि कोई फ़्लोटिंग पॉइंट सामान नहीं है। अभिव्यक्ति का परिणाम अभिव्यक्ति को बदल देता है, जैसा echo $((1+1))कि बन जाएगाecho 2
  • ((...))को अंकगणितीय मूल्यांकन के रूप में संदर्भित किया जाता है और इसका उपयोग if ((...)); thenया while ((...)) ; doकथनों के भाग के रूप में किया जा सकता है । अंकगणितीय विस्तार विस्तार $((..))ऑपरेशन के आउटपुट को प्रतिस्थापित करता है और इसका उपयोग चर को असाइन करने के लिए किया जा सकता है, i=$((i+1))लेकिन सशर्त विवरणों में इसका उपयोग नहीं किया जा सकता है।
  • $[...] अंकगणित के विस्तार के लिए पुराना वाक्यविन्यास है जो कि पदावनत है। यह भी देखें । यह संभवत: इसलिए रखा गया था ताकि पुरानी bashस्क्रिप्ट न टूटें। इसमें काम नहीं किया गया ksh93, इसलिए मेरा अनुमान है कि यह सिंटैक्स बैश-विशिष्ट है। नोट : रिक्त स्थान यहाँ बहुत महत्वपूर्ण हैं; $[1+1]सामान के साथ भ्रमित मत करो [ $a -eq $b ][रिक्त स्थान के साथ के रूप में जाना जाता है testआदेश, और आप आम तौर पर निर्णय लेने की कुछ हिस्सों में यह देखते हैं। यह व्यवहार और उद्देश्य में बहुत अलग है।
  • letएक bashऔर kshकीवर्ड है जो सरल अंकगणितीय मूल्यांकन के साथ चर निर्माण की अनुमति देता है। यदि आप एक स्ट्रिंग को वहां असाइन करने का प्रयास करते हैं जैसे let a="hello world"कि आपको सिंटैक्स त्रुटि मिलेगी। में काम करता है bashऔर ksh93
  • $(...)कमांड प्रतिस्थापन है, जहां आप सचमुच एक कमांड का आउटपुट लेते हैं और एक चर को असाइन करते हैं। यहां आपकी आज्ञा है expr, जो स्थैतिक तर्क लेता है, जैसे expr arg1 arg2 arg3, इसलिए रिक्त स्थान महत्वपूर्ण हैं। यह पूर्णांक अंकगणित के लिए एक छोटे कमांड-लाइन कैलकुलेटर की तरह है, साथ ही कुछ सही / गलत और regex प्रकार का सामान। यह एक शेल-न्यूट्रल कमांड है।

यह भी ध्यान देने योग्य है कि अंकगणितीय विस्तार और कमांड प्रतिस्थापन POSIX मानक द्वारा निर्दिष्ट हैं , जबकि letऔर $[...]नहीं।


1
((...))वास्तव में असाइनमेंट के लिए इस्तेमाल किया जा सकता है bash, kshऔर zsh: n=10; ((n+=10)); echo $n20 ((x=1)); echo $xप्रिंट करता है और 1. प्रिंट करता है
एलेक्सज मगुरा

1
@Alexej धन्यवाद। उत्तर अपडेट किया गया, वह भाग हटा दिया गया
सर्गी कोलोडाज़नी

11
  • letकमांड अंकगणित मूल्यांकन करता है और एक शेल बिल्ट-इन है।

    • यह आदेश चलाएँ और आपको कुछ भी नहीं मिलेगा (केवल मूल्यांकन करता है):

      let 1+2
  • $(( ))का उपयोग अंकगणितीय विस्तार करने के लिए किया जाता है : यहाँ पढ़ें

    • इसे चलाएं और आपको एक त्रुटि मिलेगी (विस्तार के कारण):

      $((1+2))
  • $[ ] अंकगणितीय विस्तार के लिए पुराना वाक्यविन्यास है:

    पुराना प्रारूप $ [अभिव्यक्ति] पदावनत है और बैश के आगामी में हटा दिया जाएगा। बैश मैन पेज

  • expr एक बाइनरी कमांड है, यदि आप कमांड सबसिस्टम के भीतर अंकगणितीय विस्तार करना चाहते हैं तो आप इसका उपयोग कर सकते हैं:

    echo $(expr 1 + 2) 
    echo `expr 1 + 2`

4

ऊपर दिए गए कुछ उत्तरों के बाद से ksh93यह विशेष रूप से ध्यान देने योग्य है कि यह फ्लोटिंग पॉइंट गणित कर सकता है, जैसे:

$ print $((1.0/3)) 
0.333333333333333333

आप प्रिंटफ के साथ आउटपुट की शुद्धता को नियंत्रित कर सकते हैं, जैसे:

$ printf "%.4f\n" $((1.0/3))
0.3333

ऊपर दिए गए फ्लोटिंग-पॉइंट नंबर के रूप में कम से कम एक तर्क निर्दिष्ट किया जाना चाहिए। यदि दोनों पूर्णांक के रूप में निर्दिष्ट किए जाते हैं तो केवल पूर्णांक गणित किया जाता है, जैसे:

$ print $((1/3))  
0

यह तब सहायक हो सकता है जब आपको शेल स्क्रिप्ट में फ्लोटिंग पॉइंट गणित की आवश्यकता होती है क्योंकि आप बाहरी कमांड को कॉल करने से बच सकते हैं।


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

1

letक्रोन में काम नहीं करता है। मुझे लगता है कि letइसका अपना वातावरण होने के कारण है। का प्रयोग करें $((...))यह के POSIX के बाद से। उदाहरण के लिए,

let x=1+2
echo x=$x

क्रॉन में, परिणाम "x =", लेकिन शेल से चलने पर "x = 3"।

x=$((1+2))
echo x=$x

सभी मामलों में "x = 3" परिणाम।

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