"#! / Bin / sh -a" में -a sed और "सेट -a" को प्रभावित क्यों नहीं करता है?


20

अगर मैं निम्नलिखित .sh फ़ाइल चलाता हूं:

#!/bin/sh -a
echo "a" | sed -e 's/[\d001-\d008]//g'

परिणाम एक त्रुटि है:

sed: -e अभिव्यक्ति # 1, char 18: अमान्य श्रेणी अंत

लेकिन अगर मैं निम्नलिखित .sh फ़ाइल चलाता हूँ:

#!/bin/sh
set -a
echo "a" | sed -e 's/[\d001-\d008]//g'

यह बिना किसी त्रुटि के चलता है। क्या दूसरा कोड पहले वाले के बराबर नहीं है? पहले एक में त्रुटि क्यों?


सभी shसमान नहीं हैं। और न ही सभी सेड बराबर हैं। जो shआप उपयोग कर रहे हैं? किस OS में? और कौन सा sed (हो सकता है? sed --versionयदि यह विफल नहीं है)?
इसहाक

1
इश्यू के आसपास काम करने के लिए कॉल के लिए सेटिंग LC_COLLATE=C(या POSIX)sed
जेफ स्कॉलर

4
एक अंतर जो मैंने पाया: पहली स्क्रिप्ट POSIXLY_CORRECT=yपर्यावरण में sed (और संभवतः किसी भी अन्य उपयोगिता) को आमंत्रित करती है, दूसरा POSIXLY_CORRECTपर्यावरण में नहीं है । जिस शेल से मैं दोनों स्क्रिप्टों को आमंत्रित करता हूं POSIXLY_CORRECT, उसके वातावरण में नहीं है।
मार्क प्लॉटनिक

1
आह, echo "a" | POSIXLY_CORRECT=y sed -e 's/[\d001-\d008]//g' अपनी समस्या को पुन: पेश करें
आइजैक

1
यह पुष्टि करते हुए कि उपरोक्त मेरे लिए ठीक उसी तरह विफल है जैसा कि ओपी ने CentOS 7.x - GNU बैश, संस्करण 4.2.46 (2) -release (x86_64-redhat-linux-gnu) और CentOS Linux 7.5.1804 (Core) पर दिखाया है ।
स्लम

जवाबों:


31

जब नाम के साथ बैश कहा जाता है sh, तो यह ऐसा करता है :

if (shell_name[0] == 's' && shell_name[1] == 'h' && shell_name[2] == '\0')
    act_like_sh++;

और फिर बाद में POSIXLY_CORRECTशेल चर कोy निम्न पर सेट करता है :

if (act_like_sh)
  {
    bind_variable ("POSIXLY_CORRECT", "y", 0);
    sv_strict_posix ("POSIXLY_CORRECT");
  }

bind_variableकॉल bind_variable_internal, जो, यदि शेल विशेषता aउस समय है (जो कि यदि आप शेल को इनवैलिड करते हैं तो यह होगा -a), निर्यात किए गए शेल वैरिएबल को चिह्नित करता है

तो अपनी पहली स्क्रिप्ट में:

#!/bin/sh -a
echo "a" | sed -e 's/[\d001-\d008]//g'

sedPOSIXLY_CORRECT=yइसके वातावरण के साथ लागू किया जाता है, जो इसके बारे में शिकायत करेगा [\d001-\d008]। (अगर सीड को --posixविकल्प दिया जाता है तो समान बात होती है ।)

जीएनयू sed में, चरित्र जिसका संख्यात्मक मूल्य में पलायन कोड है आधार -10 है NNN , लेकिन POSIX मोड में, यह एक ब्रैकेट अभिव्यक्ति के अंदर अक्षम किया गया है तो, इसका मतलब है सचमुच अक्षर, , , आदि, सीमा से होने के साथ को । वर्ण संहिताओं के क्रम में, पहले आता है (और सीमा में शून्य को छोड़कर सभी अंक शामिल हैं, साथ ही सभी बड़े अक्षर, और कुछ विशेष वर्ण)। में स्थान जो आप उपयोग कर रहे थे, पहले सॉर्ट करता है, तथापि, ताकि सीमा अमान्य है।\dNNN[\d001-\d008]\d1\1\en_US.UTF-8\1

आपकी दूसरी स्क्रिप्ट में:

#!/bin/sh
set -a
echo "a" | sed -e 's/[\d001-\d008]//g'

भले ही POSIXLY_CORRECTशेल में सेट किया गया हो, लेकिन इसका निर्यात नहीं किया जाता है, इसलिए सेड को बिना POSIXLY_CORRECTपर्यावरण के लगाया जाता है, और सेडू GNU एक्सटेंशन के साथ चलता है।

यदि आप export POSIXLY_CORRECTअपनी दूसरी स्क्रिप्ट के शीर्ष के पास जोड़ते हैं , तो आपको sed शिकायत दिखाई देगी।


6
मेरे लिए, यह एक बग है।
स्टीफन चेज़लस

1
पवित्र खोल आतंक, बैटमैन! यह एक दिलचस्प विचित्रता है (और /bin/shवास्तव में बैश होने से आने वाले मुद्दे को देखने के लिए थोड़ा बदलाव )। बैश शुरू POSIXLY_CORRECTहोने से पहले पर्यावरण में होने shपर भी ऐसा ही होता है : इसे भी उसी तरह से पारित किया जाएगा POSIXLY_CORRECT=y
इल्काचू

3
@StevenPenny, लेकिन शेल शुरू होने पर पर्यावरण में POSIXLY_CORRECT नहीं है, और स्क्रिप्ट ने इसे सेट नहीं किया है। खोल देता है। यह कहीं से भी एक पर्यावरण चर बनाता है, जो अतिरिक्त खराब है क्योंकि यह उस मोड में है जहां यह माना जाता है, और मानक-अनुरूप होने की कोशिश करता है।
ilkkachu

4
एफडब्ल्यूआईडब्ल्यू, बैश भी दस्तावेज़ को नहीं लगता है कि यह POSIXLY_CORRECTअपने आप सेट हो जाएगा । POSIX मोड के प्रभावों की सूची में इसका कोई उल्लेख नहीं है और चर विवरण केवल यह कहता है कि इसे सेट करने से शेल POSIX मोड में बदल जाता है, अन्य तरीके से नहीं।
ilkachachu

1
@ilkkachu। किया हुआ। मुझे लगता है कि POSIX कल्पना को यह स्पष्ट करने के लिए भी अपडेट किया जाना चाहिए कि चर किस चीज से प्रभावित हैं allexport
स्टीफन चेज़लस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.