सशर्त अभिव्यक्ति में "सेट-ई" के तहत "eval" का व्यवहार


10

आज्ञाओं पर विचार करें

eval false || echo ok
echo also ok

आमतौर पर, हम इसकी falseउपयोगिता को अंजाम देना चाहते हैं और, जब से निकास स्थिति गैर-शून्य है, तब निष्पादित echo okऔर echo also ok

सभी में POSIX की तरह गोले मैं का उपयोग करें ( ksh93, zsh, bash, dash, OpenBSD ksh, और yash), तो ऐसा होता है, लेकिन बातें दिलचस्प अगर हम सक्षम मिलता set -e

यदि set -eप्रभाव में है, OpenBSD के shऔर kshगोले (दोनों व्युत्पन्न pdksh) स्क्रिप्ट निष्पादित करते समय समाप्त कर देंगे eval। कोई अन्य शेल ऐसा नहीं करता है।

पोसिक्स का कहना है कि विशेष अंतर्निहित उपयोगिता (जैसे eval) में एक त्रुटि गैर-इंटरैक्टिव शेल को समाप्त करने का कारण बननी चाहिए। मुझे पूरी तरह से यकीन नहीं है कि निष्पादन false"एक त्रुटि" का गठन करता है (यदि यह था, तो यह set -eसक्रिय होने से स्वतंत्र होगा )।

इसके चारों ओर काम करने का तरीका evalएक उप खोल में रखा गया है,

( eval false ) || echo ok
echo also ok

सवाल यह है कि क्या मुझे POSIX-ly सही शेल स्क्रिप्ट में ऐसा करने की उम्मीद है, या क्या यह OpenBSD के शेल में बग है? इसके अलावा, POSIX पाठ में "त्रुटि" से क्या तात्पर्य है?


अतिरिक्त जानकारी: OpenBSD के गोले कमांड के echo okसाथ और बिना दोनों को निष्पादित करेंगेset -e

eval ! true || echo ok

मेरा मूल कोड जैसा दिखता था

set -e
if eval "$string"; then
    echo ok
else
    echo not ok
fi

जो OpenBSD के गोले (इसे समाप्त करेगा) का उपयोग करने के साथ आउटपुट नहीं करेगा, और मुझे यकीन नहीं था कि यह डिजाइन द्वारा, गलती से या गलतफहमी से, या कुछ और था।not okstring=false


eval falseएक गैर-शून्य स्थिति उत्पन्न करता है इसलिए मैं set -eउस बिंदु पर स्क्रिप्ट को समाप्त करने की उम्मीद करूंगा । के ! set -eरूप में लागू नहीं होता है के मामले में !स्पष्ट रूप से बाहर निकलने की स्थिति की जाँच करता है।
fcbsd

@fcbsd क्या आप eval falseस्क्रिप्ट को समाप्त करने की उम्मीद करेंगे भले ही यह AND-OR सूची या सशर्त विवरण का हिस्सा हो? मैं नहीं होगा
Kusalananda

मुझे यकीन नहीं है कि अगर set -eसेट किया गया है तो यह सही व्यवहार है ... मैं सहमत हूं कि यह एक सशर्त बयान में समाप्त नहीं होने के लिए समझ में आता है।
fcbsd

CentOS 7 पर sh के साथ कुछ और खेला जा रहा है - मैं कहूंगा कि OpenBSD के ksh / sh के लिए अभिप्रेत व्यवहार है, set -eइसलिए `()` का उत्तर है।
fcbsd

जवाबों:


4

किसी अन्य शेल को इस तरह के वर्कअराउंड की आवश्यकता नहीं है यह एक मजबूत संकेत है कि यह OpenBSD ksh में बग है। वास्तव में, ksh93 ऐसा मुद्दा नहीं दिखाता है।

वहाँ एक है कि ||कमांड लाइन खोल यह की बाईं ओर 1 के बदले कोड की वजह से बाहर निकलने से बचना चाहिए में।

एक विशेष अंतर्निहित त्रुटि की वजह से POSIX में एक गैर संवादात्मक शेल रिकॉर्डिंग से बाहर निकल जाएगा, लेकिन यह हमेशा सच नहीं होता है। continueएक लूप से बाहर निकलने की कोशिश करना एक त्रुटि है, और continueएक अंतर्निहित है। लेकिन अधिकांश गोले बाहर नहीं निकलते हैं:

continue 3

एक बिलियन जो एक स्पष्ट त्रुटि का उत्सर्जन करता है लेकिन बाहर नहीं निकलता है।

तो, बाहर निकलने falseकी set -eस्थिति कमांड के बिलिन विशेषता द्वारा नहीं ( evalइस मामले में) उत्पन्न होती है ।

सटीक शर्तें जिन पर set -eबाहर निकलेगी वे POSIX में काफी अधिक अस्पष्ट हैं।


यह उस प्रतिक्रिया को प्रतिध्वनित करता है जो मुझे ओपनबीएसडी मेलिंग सूची से मिला, लेकिन अधिक शब्दों के साथ, धन्यवाद! मैं एक उचित बग रिपोर्ट सुलझाऊंगा, और अगर कुछ नहीं होता है, तो मैं स्वयं स्रोत कोड देखूंगा।
Kusalananda

4

[क्षमा करें, यदि यह वास्तविक उत्तर नहीं है, तो जब मैं इसके बारे में सोचूंगा तो इसे अपडेट करूंगा]

मुझे स्रोत कोड पर एक नज़र थी, और मेरे निष्कर्ष हैं:

1) यह एक बग / सीमा है, इसके पीछे कुछ भी दार्शनिक नहीं है।

2) OpenBSD के ksh ( mksh) के पोर्टेबल कांटे से इसके लिए "फिक्स" बहुत खराब है, केवल चीजों को खराब कर रहा है, वास्तव में इसे ठीक किए बिना:

नया बग, अन्य सभी गोले से अलग:

mksh -ec 'eval "false; echo yup"'
yup

bash -ec 'eval "false; echo yup"'
(nothing)

अभी भी वास्तव में तय नहीं है:

mksh -ec 'eval "set -e; false" || echo yup'
(nothing)

bash -ec 'eval "set -e; false" || echo yup'
yup

आप बदल सकते हैं bashके साथ ऊपर dash, zsh, yash, ksh93, आदि

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