bash: कमांड लाइन तर्कों को कैसे पास करना है जिसमें विशेष वर्ण हैं


31

मैंने खुद को एक लिनक्स प्रोग्राम लिखा है जिसे programइनपुट के रूप में एक नियमित अभिव्यक्ति की आवश्यकता है।

मैं प्रोग्राम को bashशेल में कॉल करना चाहता हूं और प्रोग्राम में कमांड लाइन तर्क के रूप में उस नियमित अभिव्यक्ति को पास करता हूं (अन्य कमांड लाइन तर्क भी हैं)। एक सामान्य नियमित अभिव्यक्ति दिखती है

[abc]\_[x|y]

दुर्भाग्य से अक्षर [, ]और |विशेष वर्ण हैं bash। इस प्रकार, बुला रहा है

program [abc]\_[x|y] anotheragument

काम नहीं करता है। क्या किसी तरह के बच पात्रों या उद्धरण चिह्नों आदि का उपयोग करके अभिव्यक्ति को पारित करने का एक तरीका है?

(कॉलिंग program "[abc]\_[x|y] anotheragument"या तो काम नहीं कर रहा है, क्योंकि यह दो तर्कों को एक के रूप में व्याख्या करता है।)

जवाबों:


27

आप या तो यह कर सकते हैं

  1. बैकस्लैश (जैसे \[abc\]_\[x\|y\]) या के साथ प्रत्येक एकल विशेष प्रतीक से बच जाएं
  2. संपूर्ण तर्क (के रूप में "[abc]_[x|y]") को दोहराएं ।

संपादित करें: जैसा कि कुछ ने बताया है, डॉकिंगआउट चर विस्तार को रोकता नहीं है और न ही कमांड प्रतिस्थापन। इसलिए यदि आपके रेगेक्स में ऐसी कोई चीज़ है जिसकी व्याख्या उन में से एक के रूप में की जा सकती है, तो इसके बजाय एकल उद्धरणों का उपयोग करें


4
बैश में, डबल-कोटिंग का विस्तार चर या मापदंडों को बाईपास नहीं करता है , या तो फॉर्म में कमांड प्रतिस्थापन या , अंकगणितीय विस्तार , इतिहास विस्तार या बैकस्लैश एस्केप । इसके बजाय सिंगल कोट्स का इस्तेमाल करें। बैश मैनुअल का मैन पेज देखें, जिसका शीर्षक "कोटिंग" है। "$HOME""${USER:-root}""$(date)""`date`""$((1 + 2))""!!""\\"
फ्लिम्स

25

सिंगल कोट्स का इस्तेमाल करें। एकल उद्धरण सुनिश्चित करते हैं कि किसी भी वर्ण की व्याख्या नहीं की गई है।

$ printf %s 'spaces  are  not  interpreted away
neither are new lines
nor variable names $TESTING
nor square brackets [TESTING]
nor pipe characters or redirection symbols | > <
nor the semicolon ;
nor backslashes \a \b \c \\
the only thing that does not work is the single quote itself
'

यदि आपको किसी एकल उद्धरण को एम्बेड करने की आवश्यकता है तो दो समाधान हैं:

$ printf '%s\n' '[ Don'"'"'t worry, be happy! ]'
[ Don't worry, be happy! ]
$ printf '%s\n' '[ Don'\''t worry, be happy! ]'
[ Don't worry, be happy! ]

आप सही हैं। +1
एंटीक्रिस

6

प्रति man bash

तीन उद्धरण तंत्र हैं: बच चरित्र , एकल उद्धरण, और दोहरे उद्धरण।

एक गैर-उद्धृत बैकस्लैश ( \ ) बच चरित्र है । यह <newline> के अपवाद के साथ आने वाले अगले वर्ण के शाब्दिक मूल्य को संरक्षित करता है। यदि एक \ <newline> जोड़ी दिखाई देती है, और बैकस्लैश स्वयं उद्धृत नहीं किया जाता है, तो \ <newline> को एक लाइन निरंतरता के रूप में माना जाता है (अर्थात, इसे इनपुट स्ट्रीम से हटा दिया जाता है और प्रभावी रूप से अनदेखा किया जाता है)।

एकल उद्धरणों में वर्णों को संलग्न करना उद्धरणों के भीतर प्रत्येक वर्ण के शाब्दिक मूल्य को संरक्षित करता है। एकल उद्धरण के बीच एक एकल उद्धरण नहीं हो सकता है, तब भी जब एक बैकस्लैश द्वारा पूर्ववर्ती हो।

दोहरे उद्धरण चिह्नों में संलग्न करना अपवाद के साथ, उद्धरणों के भीतर सभी वर्णों के शाब्दिक मूल्य को संरक्षित करता है $ , ` , \ _ और, , जब इतिहास विस्तार सक्षम होता है ,! । अक्षर $ और ` दोहरे उद्धरण चिह्नों के भीतर अपने विशेष अर्थ को बनाए रखते हैं। बैकस्लैश अपना विशेष अर्थ केवल तभी रखता है जब निम्न वर्णों में से किसी एक का अनुसरण किया जाता है: $ , ` , , \ , या <newline> । एक दोहरे उद्धरण को दोहरे उद्धरण चिह्नों के साथ इसे बैकस्लैश के साथ पूर्ववर्ती द्वारा उद्धृत किया जा सकता है। यदि सक्षम है, तो इतिहास विस्तार। जब तक प्रदर्शन नहीं किया जाएगा! दोहरे उद्धरण चिह्नों में दिखाई देने से बैकस्लैश का उपयोग करके बच जाता है। बैकस्लैश से पहले ! हटाया नहीं गया है।

विशेष पैरामीटर * और @ का विशेष अर्थ है जब दोहरे उद्धरण में ( नीचे PARAMETERS देखें)।

$ ' स्ट्रिंग ' रूप के शब्द विशेष रूप से व्यवहार किए जाते हैं। यह शब्द ANSI C मानक द्वारा निर्दिष्ट बैकस्लैश-एस्कैप्ड वर्णों के साथ स्ट्रिंग में फैलता है । बैकस्लैश एस्केप सीक्वेंस, यदि मौजूद हैं, तो निम्नानुसार डिकोड किए जाते हैं:

       \ a      अलर्ट (घंटी)
        \ b      बैकस्पेस
        \ e 
       \ E      एक भागने वर्ण
        \ f      फॉर्म फ़ीड
        \ n      नई पंक्ति
        \ r      गाड़ी वापसी
        \ t      क्षैतिज टैब
        \ v      ऊर्ध्वाधर टैब
        \\      बैकस्लैश
        \ '      एकल उद्धरण
        \ "      दोहरे उद्धरण
        \ NNN    आठ-बिट वर्ण जिसका मान अष्ट मान nnn है
              (एक से तीन अंक)
       \ x HH    आठ-बिट वर्ण जिसका मान हेक्साडेसिमल मान HH है
              (एक या दो हेक्स अंक)
       \ u HHHH यूनिकोड (ISO / IEC 10646) चरित्र जिसका मूल्य है
              हेक्साडेसिमल मान HHHH (एक से चार हेक्स अंक)
        \ U HHHHHHH
              यूनिकोड (आईएसओ / आईईसी 10646) चरित्र जिसका मूल्य है
              हेक्साडेसिमल मान HHHHHHHH (एक से आठ हेक्स अंक)
        \ c x     एक नियंत्रण- x वर्ण

विस्तारित परिणाम एकल-उद्धृत है, जैसे कि डॉलर का चिह्न मौजूद नहीं था।

डॉलर चिह्न ( $ " स्ट्रिंग " ) से पहले एक डबल-उद्धृत स्ट्रिंग स्ट्रिंग का वर्तमान स्थान के अनुसार अनुवाद करने का कारण होगा। यदि वर्तमान स्थान C या है POSIX है , तो डॉलर चिह्न को अनदेखा कर दिया जाता है। यदि स्ट्रिंग का अनुवाद और प्रतिस्थापित किया जाता है, तो प्रतिस्थापन डबल-उद्धृत होता है।


2

आप \विशेष वर्णों के सामने एक बैकस्लैश ( ) का उपयोग कर सकते हैं ताकि वे इस तरह से बच सकें:

जॉन @ भयानक: ~ # इको ​​\ &
और

2

यद्यपि यह एक रेगेक्स के रूप में उपयोगी नहीं हो सकता है, कुछ वर्ण अनुक्रमों को बैश चर नामों के रूप में व्याख्या किया जा सकता है। ऐसा होने से रोकने और उन्हें विस्तारित होने से बचाने के लिए, दोहरे उद्धरण चिह्नों के बजाय एकल उद्धरणों का उपयोग करें:

program '[abc]_[x|y]' anotherargument

प्रत्येक तर्क को अलग-अलग उद्धृत करें (यदि उन्हें उद्धरण की आवश्यकता है) तो उन्हें स्वतंत्र तर्क के रूप में व्याख्या की जाती है। आप कुछ मामलों में सरणियों का उपयोग भी कर सकते हैं:

param_array=('[abc]_[x|y]' anotherargument)    # create an array
param_array+=(yetanother)     # append another element to the array
program "${param_array[@]}"   # use the array elements as arguments to program



0

पैटर्न कहां से आता है? क्या यह तय है या एक उपयोगकर्ता से है? क्या यह उपयोगकर्ता है जो स्थानीय प्रणाली या किसी दूरस्थ पर स्क्रिप्ट को लागू कर रहा है?

आप शेल को व्याख्या करने से रोकने के लिए डेटा को लपेटने के लिए उद्धरणों का उपयोग करते हैं। दो विकल्प हैं:

  1. डबल-कोट्स, जो अभी भी कुछ व्याख्या की अनुमति देते हैं ($ विस्तार और `backticks`)
  2. एकल-उद्धरण, जो शाब्दिक रूप से सब कुछ गुजरता है

चूँकि $regexps (अंत-पंक्ति / बफ़र) में एक मान्य वर्ण है, आप शायद regexp को रखने के लिए एकल-उद्धरण का उपयोग करना चाहते हैं, जब तक कि आप किसी चर में संग्रहीत नहीं होते। यदि आप किसी अविश्वस्त से मनमाने ढंग से डेटा ले जा रहे हैं, तो आप बदलना भी होगा 'साथ'"'"' और उसके बाद एकल उद्धरण में लपेट दें।

ध्यान दें कि [abc]_[x|y]ऐसा लगता है कि आप मेल खाना चाहते हैं xया y, जबकि यह वास्तव में तीन पात्रों में से एक से मेल खा रहा है xy|। वर्ग कोष्ठक पात्रों के भीतर और केवल -श्रेणियों के लिए और ^शुरुआत में नकार के लिए मेल खाते हैं । तो, [abc]_(x|y)आपका मतलब क्या हो सकता है और कोष्ठक ऐसे अक्षर हैं जो विशेष रूप से खोल देने वाले हैं। स्क्वायर-ब्रैकेट शेल के लिए विशेष नहीं हैं , यह सिर्फ ऐसा दिखता है जैसे वे हैं। डबल-वर्ग ब्रैकेट [[ ... ]]विशेष हैं।


यह यहां सबसे सही उत्तरों में से एक है (मैं विशेष रूप से इसके 'साथ बदलने के निर्देश की सराहना करता हूं '"'"'), हालांकि, यह अभी भी सही नहीं है। [शेल के लिए एक विशेष चरित्र है, इसका उपयोग वाइल्डकार्ड में किया जाता है जब पथ-विस्तार (जो कि शेल सब कुछ के लिए करता है)।
जेपलेसेक

यह कुछ संदर्भों में विशेष है, जैसे कि वैरिएबल सबस्क्रिप्टिंग या ग्लोबिंग के लिए, लेकिन आप अभी भी टाइप कर सकते हैं foo=a[b]और फिर echo $fooदेख सकते हैं कि स्ट्रिंग को उद्धृत करने की आवश्यकता नहीं है। तुम सही हो, मैं बहुत संक्षिप्त था।
फिल पी।

यदि आप अशुभ हैं, तो abवर्तमान निर्देशिका में एक फ़ाइल है, और फिर fooइसके abबजाय इसमें होगा a[b]। अपने वर्ग कोष्ठक, लोगों को उद्धृत करें।
क्लैक

(स्पष्टता के लिए: मैं उद्धरण करता हूं (जैसा कि मूल उत्तर स्पष्ट किया गया था, जहां मैं उद्धृत करने के लिए जोर दे रहा था), और यह एक पक्ष-उपहास है जिसे मैं संबोधित कर रहा हूं)। इस दावे ने मुझे चौंका दिया, इसलिए मैंने इसका परीक्षण किया। यह zsh या bash में सही नहीं है, लेकिन BSD / bin / sh में सच है। यह POSIX के खिलाफ है और गैर-मानक व्यवहार है, इसलिए आपको इसे संभालने के लिए उद्धृत करना होगा। Zsh में, आप setopt glob_assignइस व्यवहार को भी सक्षम कर सकते हैं, इसलिए उद्धृत करना सबसे सुरक्षित उत्तर है।
फिल पी।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.