GNU कुछ गोले के लिए {} का पता लगाता है और मास्किंग करता है - कौन सा?


34

जीएनयू खोजने के लिए आदमी पेज:

-exec command ;
    [...] The  string `{}'  is  replaced  by the current 
    file name being processed everywhere it occurs in the 
    arguments to the command, not just in arguments where 
    it is alone, as in some  versions  of  find.
    Both  of  these  constructions might need to be escaped 
    (with a `\') or quoted to protect them from expansion 
    by the shell. 

यह आदमी find(GNU खोज) 4.4.2 से है।

अब मैंने इसे बैश और डैश के साथ परीक्षण किया, और दोनों को {}नकाबपोश होने की आवश्यकता नहीं है । यहाँ एक सरल परीक्षण है:

find /etc -name "hosts" -exec md5sum {} \; 

क्या कोई शेल है, जिसके लिए मुझे वास्तव में ब्रेसिज़ की आवश्यकता है? ध्यान दें, कि यह इस बात पर निर्भर नहीं करता है कि क्या फ़ाइल में रिक्त है (बैश से आह्वान किया गया है):

find ~ -maxdepth 1 -type d -name "U*" -exec ls -d {} \; 
/home/stefan/Ubuntu One

यह पाया जाता है कि यदि मिली फ़ाइल एक सब-डिले के पास जाती है:

find ~ -maxdepth 3 -type d -name "U*" -exec bash -c 'ls -d {}' \; 
ls: cannot access /home/stefan/Ubuntu: No such file or directory
ls: cannot access One: No such file or directory

जिसके द्वारा हल किया जा सकता है:

find ~ -maxdepth 3 -type d -name "U*" -exec bash -c 'ls -d "$0"' {} \;

के विपरीत:

find ~ -maxdepth 3 -type d -name "U*" -exec bash -c 'ls -d "{}"' \; 
/home/stefan/Ubuntu One

लेकिन यह वह बात नहीं है जो मैन पेज के बारे में बात कर रहा है? तो कौन सा शेल {}एक अलग तरीके से व्यवहार करता है?


@ वोकर सीगल: आपका संपादन अच्छे इरादे से हुआ होगा, लेकिन मैंने अपने वर्तमान खोज-मैनुअल की जाँच की और आपका सुधार गलत है, आपने अपने संपादनों को संक्षेप में प्रस्तुत करने का अवसर भी गंवा दिया जो एक बुरी आदत है, इसलिए मैं आपके परिवर्तनों को वापस लेता हूं। क्षमा करें, साथी।
उपयोगकर्ता अज्ञात

ओह, अगर यह कुछ टूट गया तो इसे वापस करने के लिए धन्यवाद। मुझे याद आ रहा था कि टेक्स्ट कंपाइलर जो मैन पेज फॉर्मेट का इस्तेमाल करता है, उसे रेंडरिंग डेफिनेशन की कलाकृतियों के रूप में इन "टाइपोग्राफिक कोट्स" को जनरेट करने के लिए इस्तेमाल किया जाता है। यह सही प्रिंटआउट स्वरूपण के लिए TeX को भी प्रस्तुत कर सकता है। मैंने उद्धरणों पर ध्यान दिया क्योंकि उन्होंने वाक्य रचना हाइलाइटिंग को भ्रमित किया। मैंने माना कि कोड में उपयोग किए जाने पर असामान्य पहली बोली गलत है, और अभी भी यह मानती है। ध्यान दें कि दो परिवर्तन विवरण पाठ में थे, कोड नहीं। इसलिए यदि हम उन्हें टाइपोग्राफी के रूप में देखते हैं - सौंदर्यवादी प्रतिपादन - वे सही हैं।
वोल्कर सीगल

जानकारी आउटपुट रेंडरिंग में ऐसा लगता है, एक ही उद्धरण का उपयोग दोनों पक्षों पर किया जाता है। इसमें कोई संदेह नहीं है कि मेरे बदलाव ने इसे मूल से अलग कर दिया, आप सही हैं। लेकिन क्या इससे कोई समस्या हुई है? (मैं पहले उद्धरण में आदमी को परिभाषा देते हुए बग के रूप में मानता हूं, यह टाइपोग्राफी का एकमात्र मामला है जहां तक ​​मुझे पता है।)
वोल्कर सिएगल

मैंने अभी जाँच की: `{} 'कमांड लाइन पर काम नहीं करता है। यह तकनीकी रूप से सही है, लेकिन मुझे यह पसंद नहीं है कि जब वह कॉपी और पेस्ट करने की कोशिश करता है, तो किसी अनसुने उपयोगकर्ता को एक अजीब त्रुटि मिलती है।
वोल्कर सीगल

@VolkerSiegel: यह गद्य पाठ है, कोड नहीं, इसलिए उपयोगकर्ता यहां क्या कॉपी-पेस्ट कर सकता है? और यह 2011 से मैन पेज का एक उद्धरण है। मुझे इस बात का कोई मूल्य नहीं दिखाई देता है कि फिर मैंने मैन पेज पर सुधार क्यों किया। विषय काफी जटिल है। यदि यह आपका प्रश्न था, तो मैं आपको मैन पेज को सही ढंग से उद्धृत करने के लिए समझाने की कोशिश नहीं करूंगा, लेकिन अपने प्रश्न के लिए, मैं समझौता करने के मूड में नहीं हूं। प्रशस्ति पत्र प्रशस्ति पत्र है।
उपयोगकर्ता अज्ञात

जवाबों:


26

सारांश : अगर कभी कोई खोल था जो विस्तारित हुआ था {}, तो यह अब तक वास्तव में पुरानी विरासत सामान है।

बॉर्न शैल में और POSIX अनुरूप गोले में, कोष्ठकों ( {और }) साधारण वर्ण (जैसे नहीं होते (और )जो की तरह शब्द परिसीमक हैं ;और &, और [और ]जो वर्ण ग्लोबिंग रहे हैं)। निम्नलिखित तार को शाब्दिक रूप से मुद्रित किया जाना चाहिए:

$ echo { } {} {foo,bar} {1..3}
{ } {} {foo,bar} {1..3}

एकल ब्रेस से युक्त एक शब्द एक आरक्षित शब्द है , जो केवल विशेष है यदि यह एक कमांड का पहला शब्द है।

Ksh उपकरणों का विस्तार बॉर्न शेल के असंगत विस्तार के रूप में होता है। इसके साथ बंद किया जा सकता है set +B। बैश इस संबंध में ksh का अनुकरण करता है। Zsh लागू ब्रेस विस्तार के रूप में अच्छी तरह से; वहाँ इसके साथ बंद किया जा सकता set +Iहै या setopt ignore_bracesया emulate sh। इन {}शब्दों में से कोई भी किसी भी मामले में विस्तार नहीं करता है, तब भी जब यह एक शब्द (जैसे foo{}bar) का एक विकल्प है , तर्क में सामान्य उपयोग के कारण findऔर xargs

एकल यूनिक्स v2 नोट करता है कि

कुछ ऐतिहासिक प्रणालियों में, घुंघराले ब्रेसिज़ को नियंत्रण ऑपरेटरों के रूप में माना जाता है। भविष्य के मानकीकरण की गतिविधियों में सहायता के लिए, पोर्टेबल अनुप्रयोगों को स्वयं वर्णों का प्रतिनिधित्व करने के लिए अयोग्य ब्रेसिज़ का उपयोग करने से बचना चाहिए। यह संभव है कि आईएसओ / आईईसी 9945-2: 1993 मानक के भविष्य के संस्करण की आवश्यकता हो सकती है {और }व्यक्तिगत रूप से नियंत्रण ऑपरेटरों के रूप में व्यवहार किया जा सकता है, हालांकि {}अक्सर उपयोग किए जाने वाले find {}निर्माण के कारण टोकन को विशेष रूप से इससे छूट मिलेगी ।

यह नोट मानक के बाद के संस्करणों में गिरा दिया गया था; के लिए उदाहरणों केfind निर्विवाद उपयोग हैं {}, जैसे के लिए उदाहरण हैंxargs । ऐतिहासिक बोर्न गोले हो सकते हैं, जहाँ {}उद्धृत किया जाना था, लेकिन वे अब तक पुरानी विरासत प्रणाली होंगे।

मेरे पास जो csh कार्यान्वयन हैं, (OpenBSD 4.7, DeDb पर BSD csh , tcsh) सभी का विस्तार {foo}होता है, fooलेकिन {}अकेला छोड़ देते हैं।


1
@geekosaur: मार्कडाउन का केवल एक छोटा सा हिस्सा टिप्पणियों में काम करता है । मैं नहीं जानता कि आप क्या कहना चाह रहे हैं। यदि यह ksh et al के ब्रेस एक्सपेंशन के बारे में है, तो "Ksh के इम्प्लीमेंट्स ब्रेस विस्तार को असंगत एक्सटेंशन के रूप में" के साथ मेरे पैराग्राफ की शुरुआत पढ़ें।
गिल्स एसओ- बुराई को रोकें '

2
वह bash(देखें $BASH_VERSION) था। ब्रेस विस्तार बहुत जीवित और अच्छी तरह से है।
गीकॉर्पोरस

2
यही कारण है कि था बिंदु। {}वाक्य रचना में जन्म लिया है csh, लेकिन {}रिक्त स्ट्रिंग पर विस्तार किया। नए गोले पहचानते हैं कि यह निरर्थक है, लेकिन अभी भी कुछ पुराने हैं csh
गीकॉर्पोस

1
@geekosaur: क्या आप कह सकते हैं कि किस विशिष्ट प्लेटफॉर्म पर कौन सा विशिष्ट संस्करण है? मैं स्वयं इसका परीक्षण करना पसंद करूंगा (यदि यह लिनक्स पर संभव है) या आश्वस्त रहें, कि व्यक्ति स्वयं इसका परीक्षण करता है।
उपयोगकर्ता अज्ञात

1
@geekosaur, {}fooका विस्तार करेगा foo, लेकिन {}विस्तार करेगा {}(सिवाय बैकटिक्स के, लेकिन उद्धृत करने से कोई फायदा नहीं होगा) और इस तरह से प्रलेखित किया गया था। मैंने इसे 2BSD (पहली रिलीज़), 2.79BSD, 2.8BSD और 2.11BSD की csh के लिए सत्यापित किया।
स्टीफन चेज़लस

12

3.0.0 से पहले शेल के {}संस्करणों में उद्धृत करने की आवश्यकता है fish

$ fish -c 'echo find -exec {} \;'
find -exec  ;

और आर सी शेल में (भी akangaआधारित है rc, लेकिन नहीं es):

$ rc -c "echo find -exec {} ';'"
line 1: syntax error near '{'

वे शायद उस गोले के लेखक नहीं हैं जब जीएनयू के लेखकों को यह पता चलता है कि उन्होंने उस पाठ को लिखा था, जब से वह पाठ fishपहली बार 2005 में जारी किया गया था (जबकि वह पाठ या ऐसा ही पहले से ही 1994 में था) और rcमूल रूप से यूनिक्स खोल नहीं था।

के कुछ संस्करणों के कुछ अफवाहें हैं csh(शेल ने ब्रेस विस्तार की शुरुआत की) इसकी आवश्यकता है। लेकिन csh2BSD में पहली रिलीज के बाद से उन लोगों को श्रेय देना मुश्किल है । यहाँ एक PDP11 एमुलेटर में परीक्षण किया गया है:

# echo find -exec {} \;
find -exec {} ;

और 2BSDcsh का मैन पेज स्पष्ट रूप से बताता है :

एक विशेष मामले के रूप में `{',`}' और `{} 'को अविभाजित कर दिया जाता है।

तो मुझे यह बहुत अजीब लगेगा अगर बाद में csh या tsh के बाद के संस्करण ने इसे तोड़ दिया।

यह कुछ संस्करणों में कुछ बग के आसपास काम करने के लिए हो सकता था। अभी भी उस 2BSD csh के साथ (जो 2.79BSD, 2.8BSD, 2.11BSD में समान है):

# csh -x
# echo foo {} bar
echo foo {} bar
foo {} bar
# echo `echo foo {} bar`
echo `echo foo {} bar`
echo foo {} bar
foo  bar

हालांकि उद्धरण मदद नहीं करता है:

# echo `echo foo '{}' bar`
echo `echo foo '{}' bar`
echo foo {} bar
foo  bar

आप पूरे कमांड प्रतिस्थापन को उद्धृत कर सकते हैं:

# echo "`echo foo {} bar`"
echo `echo foo {} bar`
echo foo {} bar
foo {} bar

लेकिन वह उस बाहरी प्रतिध्वनि के लिए एक तर्क दे रहा है।

में cshया tcsh, आप उद्धृत करने के लिए आवश्यकता होगी {}में की तरह जब पर अपनी नहीं खुद:

find . -name '*.txt' -type f -exec cp {} '{}.back' \;

(हालांकि उस तरह का findउपयोग पोर्टेबल नहीं है क्योंकि कुछ findकेवल {}अपने दम पर विस्तार करते हैं)।


1

एक शब्द में, cshbashऔर अन्य आधुनिक गोले यह स्वीकार करते हैं कि उपयोगकर्ता संभवतः अशक्त ब्रेस विस्तार के लिए नहीं कह रहा है। (आधुनिक cshवास्तव में है tcshऔर {}अब तक पूरी तरह से संभाल सकता है ।)


सुनकर अच्छा लगा, लेकिन मैं इसके विपरीत पूछ रहा हूं, एक ऐसा शेल जिसके लिए इसे पूरी तरह से संभालना नहीं है।
उपयोगकर्ता अज्ञात

आप यह मान रहे हैं कि कोई व्यक्ति अतिरिक्त पृष्ठ को केवल इसलिए उद्धृत करने के लिए जानकारी पृष्ठ के संदर्भ को चीर जाएगा, क्योंकि लिनक्स सिस्टम में सभी नए हैं csh। हर कोई लिनक्स पर GNU उपयोगिताओं को नहीं चलाता है; वास्तव में यह पुराने वाणिज्यिक यूनिक्स सिस्टम पर उन्हें स्थापित करने के लिए काफी सामान्य है जिनकी बंडल कमांड सीमित हैं। ( cshउन प्रणालियों पर प्रतिस्थापित करने की संभावना कम है, क्योंकि सिस्टम स्क्रिप्ट मूल की अज्ञातताओं पर भरोसा कर सकती हैं csh, और भले ही उपयोगकर्ता सभी को एक नए का उपयोग करने के लिए कॉन्फ़िगर किया गया था csh, rootनिश्चित रूप से बंडल संस्करण बने रहने की आवश्यकता होगी।)
geekosaur

2
नहीं, मैं एक आदमी के साथ बहस में हूं जो कहता है, कि हमारी विकि में हमें हर समय "{}" का उपयोग करने की सलाह देनी चाहिए, क्योंकि आदमी पृष्ठ ऐसा कहता है। और अब मैं जानना चाहूंगा कि क्या कोई ऐसा शेल है जिसका मैं उपयोग नहीं कर रहा हूं, जैसे ksh, zsh, tsh, csh या XYZsh जो मुझे नहीं पता, जिसके लिए यह दावा सही है, या क्या मैं ईमानदारी से मान सकता हूं, कि वहाँ नहीं है यदि विभिन्न यूनिक्स के लिए गोले हैं जिन्हें "{}" की आवश्यकता है, तो यह एक अच्छा स्पष्टीकरण होगा कि वाक्य अभी भी मैन पेज में क्यों है, लेकिन लिनक्स शुरुआती के लिए सलाह के रूप में उपयुक्त नहीं है।
उपयोगकर्ता अज्ञात

अब मैं अगर सोच रहा हूँ pdksh... सही बात करता है, हालांकि करने के लिए सही जवाब है कि शायद है "असली kshFOSS इन दिनों है।"
geekosaur

4
Pdksh, जैसे mksh, ksh93, bash और zsh, केवल ब्रेसिज़ का विस्तार करता है जब बीच में एक कॉमा होता है (या ..ksh93, bash और zsh के लिए)। केवल (t) csh का विस्तार होता {foo}है foo, और यहां तक ​​कि यह {}अकेला (कम से कम BSD के) पर भी निकल जाता है ।
गिल्स एसओ- बुराई को रोकना '
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.