मैं लिख सकता हूँ
VAR=$VAR1
VAR=${VAR1}
VAR="$VAR1"
VAR="${VAR1}"
मेरे लिए अंतिम परिणाम उसी के बारे में लगता है। मुझे एक या दूसरे को क्यों लिखना चाहिए? इनमें से कोई भी पोर्टेबल / POSIX नहीं हैं?
मैं लिख सकता हूँ
VAR=$VAR1
VAR=${VAR1}
VAR="$VAR1"
VAR="${VAR1}"
मेरे लिए अंतिम परिणाम उसी के बारे में लगता है। मुझे एक या दूसरे को क्यों लिखना चाहिए? इनमें से कोई भी पोर्टेबल / POSIX नहीं हैं?
जवाबों:
VAR=$VAR1
का एक सरलीकृत संस्करण है VAR=${VAR1}
। ऐसी चीजें हैं जो दूसरा कर सकती हैं, उदाहरण के लिए, सरणी इंडेक्स (पोर्टेबल नहीं) के संदर्भ में या सबस्ट्रिंग (POSIX-पोर्टेबल) को हटा सकती है। POSIX कल्पना में शुरुआती और पैरामीटर विस्तार के लिए बैश गाइड के चर खंड पर और देखें ।
के रूप में rm -- "$VAR1"
या एक चर के आसपास उद्धरण का उपयोग करना rm -- "${VAR}"
एक अच्छा विचार है। यह चर की सामग्री को एक परमाणु इकाई बनाता है। यदि चर मान में रिक्त स्थान (अच्छी तरह से, $IFS
विशेष चर में वर्ण , डिफ़ॉल्ट रूप से रिक्त) या ग्लोबबिंग वर्ण हैं और आप इसे उद्धृत नहीं करते हैं, तो प्रत्येक शब्द को फ़ाइल नाम पीढ़ी (ग्लोबिंग) के लिए माना जाता है, जिसका विस्तार जो कुछ भी आप के लिए तर्क देता है 'कर रहे हैं।
$ find .
.
./*r*
./-rf
./another
./filename
./spaced filename
./another spaced filename
./another spaced filename/x
$ var='spaced filename'
# usually, 'spaced filename' would come from the output of some command and you weren't expecting it
$ rm $var
rm: cannot remove 'spaced': No such file or directory
# oops! I just ran 'rm spaced filename'
$ var='*r*'
$ rm $var
# expands to: 'rm' '-rf' '*r*' 'another spaced filename'
$ find .
.
./another
./spaced filename
./another spaced filename
$ var='another spaced filename'
$ rm -- "$var"
$ find .
.
./another
./spaced filename
पोर्टेबिलिटी पर: POSIX.1-2008 खंड 2.6.2 के अनुसार , घुंघराले ब्रेसिज़ वैकल्पिक हैं।
var1=$var
विस्तार एक त्रुटि देता है?
export VAR=$VAR1
। ब्रेसिज़ के लिए के रूप में, वे वैकल्पिक हैं (आपके द्वारा उद्धृत अनुभाग के चौथे पैराग्राफ की जांच करें; यह सभी पूर्व-पॉसिक्स और पोसिक्स गोले में मामला है)।
${VAR}
और $VAR
बिल्कुल बराबर हैं। एक सादे चर विस्तार के लिए, उपयोग करने का एकमात्र कारण यह है ${VAR}
कि जब पार्सिंग अन्यथा चर नाम में कई वर्णों को पकड़ लेगा, जैसा कि ${VAR1}_$VAR2
(जिसमें ब्रेसिज़ के बिना बराबर होगा ${VAR1_}$VAR2
)। अधिकांश सजी विस्तार ( ${VAR:=default}
, ${VAR#prefix}
, ...) ब्रेसिज़ की आवश्यकता है।
एक चर असाइनमेंट में, फील्ड स्प्लिटिंग (यानी वैल्यू में व्हाट्सएप पर विभाजित करना) और pathname का विस्तार (यानी ग्लोबिंग) बंद हो जाता है, इसलिए सभी POSIX गोले में और सभी प्री-पॉस श में VAR=$VAR1
बराबर है VAR="$VAR1"
जो मैंने सुना है । (POSIX रेफ: सरल कमांड )। उसी कारण से, शाब्दिक रूप से शाब्दिक स्ट्रिंग पर VAR=*
सेट VAR
होता है *
; निश्चित रूप से VAR=a b
सेट VAR
करने के लिए a
के बाद से b
पहली जगह में एक अलग शब्द है। सामान्य शब्दों में, दोहरे उद्धरण चिह्नों जहां खोल वाक्य रचना उदाहरण के लिए, एक शब्द भी उम्मीद अनावश्यक हैं मेंcase … in
(लेकिन पैटर्न में नहीं), लेकिन फिर भी वहाँ आपको सावधान रहने की जरूरत है: उदाहरण के लिए POSIX यह बताता है किरीडायरेक्शन लक्ष्य ( >$filename
) को स्क्रिप्ट्स में उद्धृत करने की आवश्यकता नहीं है, लेकिन बैश सहित कुछ गोले को स्क्रिप्ट में भी दोहरे उद्धरण चिह्नों की आवश्यकता होती है। देखें कि डबल-कोटिंग कब आवश्यक है? अधिक गहन विश्लेषण के लिए।
आपको कई मामलों में विशेष रूप से export VAR="${VAR1}"
(जो कि समान रूप से लिखा जा सकता है export "VAR=${VAR1}"
) कई मामलों में दोहरे उद्धरण चिह्नों की आवश्यकता होती है (POSIX इस मामले को खुला छोड़ देता है)। साधारण असाइनमेंट के साथ इस मामले की समानता, और उन मामलों की सूची की बिखरी हुई प्रकृति जहां आपको दोहरे उद्धरण चिह्नों की आवश्यकता नहीं है, यही कारण है कि मैं सिर्फ दोहरे उद्धरण चिह्नों का उपयोग करने की सलाह देता हूं जब तक आप विभाजित और ग्लोब नहीं करना चाहते।
IFS
वर्ण नहीं होगा क्योंकि मैं आदत में रहना चाहता हूं। एक अपवाद यह है कि मैं वैरिएबल असाइनमेंट करते समय मूल्य को उद्धृत नहीं करता (जब तक कि आवश्यकता न हो, जैसे कि मान में कोई स्थान होता है)। यह कमांड सिंटैक्स हाइलाइट करता है जब कमांड सब्स्टीट्यूशन जैसे कि होते हैं FOO=$(BAR=$(BAZ=blah; printf %s "${BAZ}"); printf %s "${BAR}")
। सब कुछ "स्ट्रिंग" रंग में रंगने के बजाय, मुझे नेस्टेड कोड का सिंटैक्स हाइलाइटिंग मिलता है। यही कारण है कि मैं बैकटिक्स से बचता हूं।
>$file
POSIX लिपियों में ठीक है, तो यह और भी जब गैर-सहभागी (जब तक POSIX अनुपालन के साथ लागू की जाती है बैश में नहीं है $POSIXLY_CORRECT
या --posix
...)।
VAR=$VAR1
, मुझे कभी-कभी आश्चर्य होता है local VAR=$VAR1
, जिसे मैं कुछ मामलों में अलग-अलग तरीके से काम करना याद रखता हूं, कम से कम कुछ गोले में। लेकिन, मैं विचलन को पुन: पेश नहीं कर सकता।
local VAR=$VAR1
की तरह है export VAR=$VAR1
, यह शेल पर निर्भर करता है।
विचार करें कि डबल-उद्धरण का उपयोग चर विस्तार के लिए किया जाता है, और एकल-उद्धरण का उपयोग मजबूत-उद्धरण के लिए किया जाता है, अर्थात, विस्तार का उपयोग।
this='foo'
that='bar'
these="$this"
those='$that'
for item in "$this" "$that" "$these" "$those"; do echo "$item"; done
foo
bar
foo
$that
यह उल्लेख करना सार्थक हो सकता है कि आपको कई कारणों से जहां भी संभव हो उद्धरण का उपयोग करना चाहिए, जिनमें से सबसे अच्छा है कि इसे सबसे अच्छा अभ्यास माना जाता है, और पठनीयता के लिए। इसके अलावा, क्योंकि बैश कई बार और अक्सर प्रतीत होता है अतार्किक या अनुचित / अप्रत्याशित तरीकों के लिए, और उद्धरण स्पष्ट रूप से अंतर्निहित अपेक्षाओं को बदल देता है, जो उस त्रुटि सतह (या संभावित-के लिए) को कम कर देता है।
और जब यह बोली न करने के लिए पूरी तरह से कानूनी है , और ज्यादातर मामलों में काम करेगा, तो सुविधा के लिए कार्यक्षमता प्रदान की जाती है और शायद कम पोर्टेबल है। इरादा और अपेक्षा को प्रतिबिंबित करने के लिए पूरी तरह से औपचारिक अभ्यास की गारंटी है।
अब यह भी विचार करें कि निर्माण "${somevar}"
का उपयोग प्रतिस्थापन कार्यों के लिए किया जाता है। कई उपयोग के मामले, जैसे प्रतिस्थापन और सरणियाँ।
thisfile='foobar.txt.bak'
foo="${thisfile%.*}" # removes shortest part of value in $thisfile matching after '%' from righthand side
bar="${thisfile%%.*}" # removes longest matching
for item in "$foo" "$bar"; do echo "$item"; done
foobar.txt
foobar
foobar='Simplest, least effective, least powerful'
# ${var/find/replace_with}
foo="${foobar/least/most}" #single occurrence
bar="${foobar//least/most}" #global occurrence (all)
for item in "$foobar" "$foo" "$bar"; do echo "$item"; done
Simplest, least effective, least powerful
Simplest, most effective, least powerful
Simplest, most effective, most powerful
mkdir temp
# create files foo.txt, bar.txt, foobar.txt in temp folder
touch temp/{foo,bar,foobar}.txt
# alpha is array of output from ls
alpha=($(ls temp/*))
echo "$alpha" # temp/foo.txt
echo "${alpha}" # temp/foo.txt
echo "${alpha[@]}" # temp/bar.txt temp/foobar.txt temp/foo.txt
echo "${#alpha}" # 12 # length of first element (implicit index [0])
echo "${#alpha[@]}" # 3 # number of elements
echo "${alpha[1]}" # temp/foobar.txt # second element
echo "${#alpha[1])" # 15 # length of second element
for item in "${alpha[@]}"; do echo "$item"; done
temp/bar.txt
temp/foobar.txt
temp/foo.txt
यह सब "${var}"
घटिया निर्माण की सतह को मुश्किल से खरोंच रहा है। बैश शेल स्क्रिप्टिंग के लिए निश्चित संदर्भ ऑनलाइन संदर्भ है, टीएलडीपी द लिनक्स डॉक्यूमेंटेशन प्रोजेक्टhttps://www.tldp.org/LDP/abs/html/parameter-substitution.html
ls -la
lrwxrwxrwx. 1 root root 31 Nov 17 13:13 prodhostname
lrwxrwxrwx. 1 root root 33 Nov 17 13:13 testhostname
lrwxrwxrwx. 1 root root 32 Nov 17 13:13 justname
फिर अंत:
env=$1
if [ ! -f /dirname/${env}hostname ]
कर्ल का उपयोग करने के एक स्पष्ट उदाहरण के रूप में ध्यान देने योग्य है