बैश में संभावित बग ?: फू () {गूंज "$ {var [0]}"; }; var = (बार बाज) फू


22

OS : उबंटू 16.04.3

शैल : बैश 4.3.48


मुझे पता है कि अस्थायी रूप में के रूप में एक चर की सामग्री को बदलने के लिए संभव है var=value command, शायद जा रहा है IFS= read -r varइस का सबसे उल्लेखनीय मामला।

और, ग्रेग की विकी के लिए धन्यवाद , मैं भी समझता हूं:

# Why this
foo() { echo "$var"; }
var=value foo

# And this does work
var=value; echo "$var"

# But this doesn't
var=value echo "$var"

मेरी समझ से क्या बचता है:

$ foo() { echo "${var[0]}"; }
$ var=(bar baz) foo
(bar baz)

जहां तक ​​मुझे पता है (और पिछले उदाहरणों के तर्क का अनुसरण), तो इसे प्रिंट करना चाहिए bar, नहीं (bar baz)

क्या यह केवल मेरे लिए होता है? क्या यह इच्छित व्यवहार है और मुझे कुछ याद आ रहा है? या यह एक बग है?


3
शायद यह इस तथ्य के साथ कुछ करना है कि बैश पर्यावरण चर के रूप में सरणियों का समर्थन नहीं करता है?

3
@ जेसे_ब शायद। हालांकि जब मैं export var=(foo bar); echo "${var[0]}"इसे प्रिंट करता हूं foo, तो नहीं (foo bar)
nxnev

1
अजीब है, कि मेरे लिए भी काम किया। और इसके इस्तेमाल से exportपता चलता है:declare -ax var=([0]="foo" [1]="bar")
जेसी_ब

3
पर्यावरण में सरणियाँ नहीं हो सकती हैं, AFAIK। उदाहरण के लिए, export i_am_array=(foo bar); /usr/bin/env | grep i_am_arrayयहां कोई आउटपुट नहीं दिया गया है।
derobert

3
इसके अलावा: इसकी पुष्टि करता foo() { declare -p var; } ; var=(bar baz) fooहै declare -x var="(bar baz)"कि इसे एक स्ट्रिंग के रूप में माना जाता है, न कि एक सरणी
derobert

जवाबों:


19

आम तौर पर बुला:

var=value cmd

जहां cmdएक समारोह पोर्टेबल नहीं है।

साथ bash, कि केवल अदिश चर के लिए काम करता है (और साथ x=(...)एक सरणी के रूप में पार्स लेकिन एक अदिश के रूप में नियुक्त) और यदि आप उस, कर के साथ देखते हुए साथ कई मुद्दों देखते हैं ksh93और yash, यह काम करता है लेकिन चर परिभाषा बाद में बनी हुई है। के साथ mksh, आपको एक सिंटैक्स त्रुटि मिलती है। बॉर्न शेल में, यह स्केलर चर के लिए भी बिल्कुल भी काम नहीं करता था।

यह भी ध्यान दें कि स्केलर चर के साथ, भले ही चर समाप्त हो रहा है फ़ंक्शन के भीतर निर्यात किया जा रहा है (जो कि निष्पादित किए जा रहे कमांड के लिए पारित किया गया है) शेल से शेल में भिन्न होता है (यह bash, yash, mksh, zsh में है, लेकिन ksh में नहीं है) राख)।

यह केवल उसी तरह से काम करता है जिस तरह से आप अपेक्षा करते हैं zsh। ध्यान दें कि zshसरणी सूचकांक 1 से शुरू होते हैं।

bash-4.4$ zsh
$ a=(before value)
$ f() echo $a[1]
$ a=(temp value) f
temp
$ echo $a[1]
before

12

यह सिर्फ एक बग नहीं है, यह एक ऐसी सुविधा है जो कभी भी बिना किसी योजना के लागू होती है। इस मेलिंग सूची के बाद 2014 से निर्माता से है:

सौभाग्य से, 4.3 बैच (25 फुट) में, आप सिर्फ -DARRAY_EXPORT नहीं कर सकते हैं और सरणी चर आयात / निर्यात प्राप्त कर सकते हैं। कोड संकलित नहीं करता है, और यदि आप इसे ठीक करते हैं, तो यह लिंक नहीं करता है, और यदि आप इसे ठीक करते हैं, तो ठीक है, आप निम्नलिखित समस्या को समाप्त करते हैं।

यह सिर्फ इसके लिए जाने के लिए एक टन की परेशानी है। सरणी निर्यात को सक्षम करने की मेरी कोई योजना नहीं है।

बैश के लिए नवीनतम गिट रेपो से खींचना इस में है variables.c:

  #  if ARRAY_EXPORT
        /* Array variables may not yet be exported. */

यह सुझाव देते हुए कि जो कुछ भी है वह पूर्ण नहीं है।


5
यहां, यह एक फ़ंक्शन के लिए है, इसलिए कुछ भी निर्यात करने का कोई सवाल नहीं है क्योंकि इसमें कोई execve()सिस्टम कॉल शामिल नहीं है। zshएक शेल के लिए देखें जो एक सरणी के साथ कॉलिंग फ़ंक्शन का समर्थन करता है जो अस्थायी रूप से उस तरह से सेट करता है।
स्टीफन चेज़लस

@ StéphaneChazelas लेकिन कार्य पूरा होने के बाद पर्यावरण बदलता है (एक नया चर जोड़कर) और फिर वापस लौट जाता है (मैं इस मामले के बारे में हूं:) my_var=one func_bar। क्या हम कह सकते हैं, कि exportपर्यावरण से जुड़ रहा है और इस प्रकार, निर्यात का उपयोग यहां हुड के तहत किया जाता है? मेरे उत्तर को देखें, मैंने प्रदर्शन कोड जोड़ा।
मिनीमैक्स

10

से man bashकी बग धारा (के संस्करण bash4.3 है):

बग

   Array variables may not (yet) be exported.

अगला कोड दर्शाता है, कि एक अस्थायी चर वातावरण में मौजूद है, केवल जब फ़ंक्शन चल रहा है। जब फ़ंक्शन पूरा हो जाता है, तो अस्थायी चर गायब हो जाता है।

### defining the "bar" function
### it pass all environment variables to the "grep" command
### and the "grep" prints the only "my_var" variable from it
bar() { env | grep my_var=; }

### calls the "bar" function with the temporary 
### variable "my_var" created and assigned.
my_var=one bar

my_var=one         ### The output. The environment contains the "my_var" variable

### checks, does the environment still have the "my_var" variable
### (It doesn't have.)
env | grep my_var=
                   ### The output is empty,
                   ### the environment doesn't contain the "my_var" variable

सम्बंधित जानकारी:

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