expr कोष्ठक की तरह नहीं लगता है (स्पष्ट ऑपरेटर प्राथमिकता के लिए गणित में प्रयुक्त):
expr 3 * (2 + 1)
bash: syntax error near unexpected token `('
बाश में ऑपरेटर प्राथमिकता को कैसे व्यक्त करें?
expr कोष्ठक की तरह नहीं लगता है (स्पष्ट ऑपरेटर प्राथमिकता के लिए गणित में प्रयुक्त):
expr 3 * (2 + 1)
bash: syntax error near unexpected token `('
बाश में ऑपरेटर प्राथमिकता को कैसे व्यक्त करें?
जवाबों:
letबैश बिलिन का उपयोग करने का दूसरा तरीका :
$ let a="3 * (2 + 1)"
$ printf '%s\n' "$a"
9
ध्यान दें
जैसा कि @ स्टीफन चेज़ेलस ने कहा , bashआपको विरासत में या उससे ((...))अधिक अंकगणित करने के लिए उपयोग करना चाहिए ।exprlet
पोर्टेबिलिटी के लिए $((...)), @ बर्नहार्ड जवाब की तरह उपयोग करें ।
let। यह किसी भी अधिक मानक या पोर्टेबल की तुलना में नहीं है (( a = 3 * (2 + 1) ))(दोनों से आते हैं kshऔर केवल ksh, bash और zsh में उपलब्ध हैं) और यह कम सुपाठ्य या उद्धरण के लिए आसान है। a=$((3 * (2 + 1)))पोर्टेबल होने के लिए उपयोग करें ।
((a = 3 * (2 + 1) ))लिए एक है, पोर्टेबिलिटी के लिए एक a=$((3 * (2 + 1)))), इसलिए यह आपके या आपके उत्तर के खिलाफ नोट नहीं है लेकिन इसके लिए चयनित उत्तर होने के खिलाफ है और शीर्ष स्कोरर।
a=1 $[a+2]या a=1 b=2 $[a+b]। क्या उनका कारण उस वाक्य रचना से बचना है?
आप इसके बजाय अंकगणितीय विस्तार का उपयोग कर सकते हैं।
echo "$(( 3 * ( 2 + 1 ) ))"
9
मेरी व्यक्तिगत राय में, यह प्रयोग करने की तुलना में थोड़ा अच्छा है expr।
से man bash
अंकगणित विस्तार अंकगणित विस्तार एक अंकगणितीय अभिव्यक्ति के मूल्यांकन और परिणाम के प्रतिस्थापन की अनुमति देता है। अंकगणितीय विस्तार के लिए प्रारूप है:
$((expression))अभिव्यक्ति को ऐसे माना जाता है जैसे कि यह दोहरे उद्धरण चिह्नों के भीतर है, लेकिन कोष्ठकों के अंदर एक दोहरे उद्धरण का विशेष रूप से व्यवहार नहीं किया जाता है। अभिव्यक्ति में सभी टोकन पैरामीटर विस्तार, स्ट्रिंग विस्तार, कमांड प्रतिस्थापन और उद्धरण हटाने से गुजरते हैं। अंकगणित विस्तार को नेस्टेड किया जा सकता है।
मूल्यांकन ARITHMETIC EVALUATION के तहत नीचे सूचीबद्ध नियमों के अनुसार किया जाता है। यदि अभिव्यक्ति अमान्य है, तो बैश एक संदेश को दर्शाता है जो विफलता का संकेत देता है और कोई प्रतिस्थापन नहीं होता है।
exprआधुनिक गोले में अंकगणित का उपयोग करने का कोई कारण नहीं है ।
POSIX $((...))विस्तार ऑपरेटर को परिभाषित करता है । तो आप सभी POSIX आज्ञाकारी गोले में ( shसभी आधुनिक यूनिक्स-पसंद, डैश, बैश, यश, mshh, zsh, पॉश, ksh ...) का उपयोग कर सकते हैं।
a=$(( 3 * (2 + 1) ))
a=$((3*(2+1)))
kshएक letबिल्टिन भी पेश किया, जो एक ही तरह की अंकगणितीय अभिव्यक्ति के रूप में दिया गया है, कुछ में विस्तार नहीं करता है, लेकिन अभिव्यक्ति के 0 या नहीं के आधार पर बाहर निकलने की स्थिति देता है, जैसे expr:
if let 'a = 3 * (2 + 1)'; then
echo "$a is non-zero"
fi
हालाँकि, जैसा कि उद्धरण इसे अजीब बनाता है और बहुत सुपाठ्य नहीं है ( exprनिश्चित रूप से उसी हद तक नहीं ), kshएक ((...))वैकल्पिक विकल्प भी प्रस्तुत किया है :
if (( a = 3 * (2 + 1) )) && (( 3 > 1 )); then
echo "$a is non-zero and 3 > 1"
fi
((a+=2))
जो बहुत अधिक सुपाठ्य है और इसके स्थान पर इसका उपयोग किया जाना चाहिए।
letऔर ((...))में ही उपलब्ध हैं ksh, zshऔर bash। $((...))वाक्य रचना प्राथमिकता दी जानी चाहिए अगर अन्य गोले को पोर्टेबिलिटी की जरूरत है, exprकेवल पूर्व POSIX बॉर्न की तरह गोले (आमतौर पर बॉर्न शैल या Almquist खोल के प्रारंभिक संस्करणों) के लिए आवश्यक है।
गैर-बॉर्न मोर्चे पर, अंतर्निहित अंकगणित ऑपरेटर के साथ कुछ गोले हैं:
csh/ tcsh(वास्तव में अंकगणित मूल्यांकन के साथ पहला यूनिक्स खोल)
@ a = 3 * (2 + 1)akanga(पर आधारित rc)
a = $:'3 * (2 + 1)'एक इतिहास के रूप में, अल्मक्विस्ट शेल के मूल संस्करण, जैसा कि 1989 में यूनेट पर पोस्ट किया गया था, में एक exprबिल्डिन (वास्तव में विलय हुआ test) था, लेकिन इसे बाद में हटा दिया गया था।
: $((a = a*2))?
$((...))जो zsh, ksh93 या यश जैसे फ्लोटिंग पॉइंट का समर्थन करता है ।
exprएक बाहरी कमांड है, यह विशेष शेल सिंटैक्स नहीं है। इसलिए, यदि आप exprशेल विशेष वर्णों को देखना चाहते हैं, तो आपको उन्हें उद्धृत करके शेल पार्सिंग से बचाने की आवश्यकता है। इसके अलावा, exprप्रत्येक संख्या और ऑपरेटर को एक अलग पैरामीटर के रूप में पारित करने की आवश्यकता होती है। इस प्रकार:
expr 3 \* \( 2 + 1 \)
जब तक आप 1970 या 1980 के दशक से एक प्राचीन यूनिक्स प्रणाली पर काम नहीं कर रहे हैं, तब तक उपयोग करने का बहुत कम कारण है expr। पुराने दिनों में, गोले में अंकगणित करने के लिए एक अंतर्निहित तरीका नहीं था, और आपको exprइसके बजाय उपयोगिता को कॉल करना था । सभी POSIX गोले में अंकगणित विस्तार सिंटैक्स के माध्यम से अंकगणित है ।
echo "$((3 * (2 + 1)))"
निर्माण $((…))अंकगणित अभिव्यक्ति (दशमलव में लिखा गया) के परिणाम तक फैलता है। बैश, अधिकांश गोले की तरह, केवल पूर्णांक अंकगणितीय मोडुलो 2 64 (या 32 बिट मशीनों पर बैश के पुराने संस्करणों और कुछ अन्य गोले के लिए मॉडुलो 2 32 ) का समर्थन करता है।
बैश एक अतिरिक्त सुविधा सिंटैक्स प्रदान करता है जब आप असाइनमेंट निष्पादित करना चाहते हैं या परीक्षण करना चाहते हैं कि कोई अभिव्यक्ति 0 है, लेकिन परिणाम के बारे में परवाह नहीं है। यह निर्माण ksh और zsh में भी मौजूद है लेकिन सादे श में नहीं।
((x = 3 * (2+1)))
echo "$x"
if ((x > 3)); then …
पूर्णांक अंकगणितीय के अलावा, exprकुछ स्ट्रिंग हेरफेर फ़ंक्शन प्रदान करता है। ये भी POSIX गोले की विशेषताओं के आधार पर तय किए गए हैं, एक को छोड़कर: यह expr STRING : REGEXPपरीक्षण करता है कि क्या स्ट्रिंग निर्दिष्ट regexp से मेल खाती है। एक POSIX शेल बाहरी उपकरणों के बिना ऐसा नहीं कर सकता है, लेकिन bash [[ STRING =~ REGEXP ]](एक अलग regexp सिंटैक्स के साथ - exprएक क्लासिक टूल है और BRE का उपयोग करता है, bash ERE का उपयोग करता है)।
जब तक आप 20-वर्षीय सिस्टम पर चलने वाली स्क्रिप्ट्स को मेनटेन नहीं कर रहे हैं, आपको यह जानने की आवश्यकता नहीं है कि exprकभी अस्तित्व में था। शेल अंकगणित का उपयोग करें।
expr foo : '\(.\)'पाठ निष्कर्षण भी करता है। bashकी BASH_REMATCHऐसी ही कुछ प्राप्त होता है। यह स्ट्रिंग तुलना भी करता है, जो कि POSIX [नहीं करता है (हालांकि कोई इसके लिए उपयोग करने के तरीकों की कल्पना कर सकता sortहै)।
उद्धरण के साथ कोष्ठक का प्रयोग करें:
expr 3 '*' '(' 2 '+' 1 ')'
9
उद्धरण को कोष्ठक के रूप में कोष्ठक की व्याख्या करने से बैश को रोकते हैं।
exprकमांड लाइन पर टोकन को रिक्त स्थान द्वारा अलग किया जाना चाहिए; इसलिए; उदाहरण के लिए, expr 3 "*" "(2" "+" "1)" काम नहीं करेगा । (इसके अलावा, BTW, आपको शायद उद्धृत करने की आवश्यकता नहीं है +।)
whileऔर [[, वे वाक्यविन्यास हैं। यदि वे कीवर्ड थे, तो उन्हें इस तरह के कमांड तर्क में व्याख्यायित नहीं किया जाएगा। आपको उद्धरण चिह्नों की आवश्यकता होती है ताकि बैश उन्हें पार्स न करे, बल्कि एक स्ट्रिंग शाब्दिक देखता है