पैरामीटर विस्तार जिसके परिणामस्वरूप रिक्त स्ट्रिंग को अलग तरीके से व्यवहार किया जाता है


10

अपडेट करें

बग-बैश मेलिंग सूची में किसी ने पुष्टि की है कि यह बग है।


यदि किसी की रुचि है, तो नवीनतम शाखा को हटाने के लिए प्रतिबद्ध है


जबकि

bash -c 'echo "${1##*""}"' _ bar

एक खाली लाइन प्रिंट करता है,

bash -c 'echo "${1##*"${1##*}"}"' _ bar

प्रिंट करता है bar

मुझे यह समझ में नहीं आता है। ${1##*}एक खाली स्ट्रिंग के लिए फैलता है, तो "${1##*}"बस के रूप ""में इलाज किया जाना चाहिए , लेकिन लगता है जैसे बैश ऐसा नहीं लगता है।

अन्य लोकप्रिय shकार्यान्वयनों में इस पर एक आम सहमति प्रतीत होती है :

$ sh -c 'echo "${1##*"${1##*}"}"' _ bar

$ ash -c 'echo "${1##*"${1##*}"}"' _ bar

$ dash -c 'echo "${1##*"${1##*}"}"' _ bar

$ ksh -c 'echo "${1##*"${1##*}"}"' _ bar

$ ksh93 -c 'echo "${1##*"${1##*}"}"' _ bar

$ mksh -c 'echo "${1##*"${1##*}"}"' _ bar

$ posh -c 'echo "${1##*"${1##*}"}"' _ bar

$ yash -c 'echo "${1##*"${1##*}"}"' _ bar

$ zsh -c 'echo "${1##*"${1##*}"}"' _ bar

$

बैश (साथ या बिना --posix) केवल एक ही है जो इसके अनुरूप नहीं है:

$ bash -c 'echo "${1##*"${1##*}"}"' _ bar
bar

और प्रसंस्करण के विकल्प के विकल्प के बिना व्यवहार अपेक्षित है:

$ bash -c 'echo "${1##*"${1+}"}"' _ bar

$ bash -c 'echo "${1##*"${2}"}"' _ bar

$ bash -c 'echo "${1##*"${2}"}"' _ bar ''

$ 

मैं वास्तव में आश्चर्य करता हूं कि क्या इसके लिए कोई स्पष्टीकरण है, जो मुझे मैनुअल में नहीं मिला। क्या यह बग है, या मानक की गलत व्याख्या है? क्या यह व्यवहार कहीं दस्तावेज है?


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


GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)एक खाली तार प्रिंट करता है
विलियम पर्ससेल

GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)प्रिंट "बार"
विलियम पर्ससेल

@William ने 4.4.20 और 5.0.11 पर परीक्षण किया और दोनों प्रिंट "बार"
oguz ismail

यह आम तौर पर विस्तार के साथ एक समस्या है। मेरे 4.4.12(3)-release, echo "${BASH##*"${BASH##*}"}"-> में /bin/bash। जबकि echo "\${BASH##*"${BASH##*}"}"-> ${BASH##*}और eval echo "\${BASH##*"${BASH##*}"}"-> रिक्त।
जेफ वाई

जवाबों:


2

यह कोई उत्तर नहीं है

पहले मैं सोच रहा था कि यह विशेष ग्लोब-नियमों के कारण है, लेकिन अंत में मुझे लगता है कि यह एक बग है। निम्नलिखित चार उदाहरणों से आपको यह महसूस होना चाहिए कि मुझे विश्वास है कि यह एक बग क्यों है:

$ bash -c 'echo "${1##*${1%%bar}}"' _ foobar        # case 1
bar
$ bash -c 'echo "${1##*${1%%foobar}}"' _ foobar     # case 2

$ bash -c 'echo "${1##*"${1%%bar}"}"' _ foobar      # case 3
bar
$ bash -c 'echo "${1##*"${1%%foobar}"}"' _ foobar   # case 4
foobar

केस 1 और केस 3 उद्धरणों में भिन्न हैं। लेकिन फ़ॉर्म ${parameter##word}का पैरामीटर विस्तार प्रक्रिया के लिए पथनाम विस्तार नियमों का उपयोग करता है word। तो *fooऔर *"foo"पथ नाम विस्तार में डबल उद्धरण के रूप में समान व्यवहार अनदेखा किया जा सकता जब तक कि वे विशेष पैटर्न पात्रों को गले लगाने के लिए है ( *, ?, ...)। यह निम्नलिखित उदाहरण में देखा गया है:

$ bash -c 'echo "${1##*${2%%b*r}}"' _ 'foobar' 'f*ob*r'
bar
$ bash -c 'echo "${1##*"${2%%b*r}"}"' _ 'foobar' 'f*ob*r'
foobar

तो अगर यह मामला है, तो केस 2 और केस 4 को अलग-अलग व्यवहार क्यों करना चाहिए?


केस 2 और केस 4 को अलग-अलग व्यवहार क्यों करना चाहिए? कोई कारण नहीं है, दोनों ${1+}और ${1+""}फैलता स्ट्रिंग खाली करने के लिए है, लेकिन वे इलाज नहीं कर रहे हैं जिस तरह से ${1##*}है (मेरी नवीनतम संपादित देखें)। इस प्रकार हम कटौती कर सकते हैं यह एक बग है, है ना?
ऑगूज़

1
@oguzismail बिल्कुल! यदि केस 1 और केस 3 समान व्यवहार करते हैं, तो केस 2 और केस 4 भी समान रूप से व्यवहार करने चाहिए।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.