क्यों `इको-ई” \\\ SOME_TEXT ”` केवल एक बैकस्लैश दिखाता है?


19

क्या कोई यह बता सकता है कि लिनक्स खोल में भागने वाले चरित्र में पर्दे के पीछे क्या हो रहा है? मैंने निम्नलिखित की कोशिश की और बहुत कुछ जाना, बिना किसी सफलता के यह समझने में कि क्या (और कैसे) चल रहा है:

root@sv01:~# echo -e "\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\\\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\\\\ Hello!"
\\\ Hello!
root@sv01:~# echo -e "\n Hello!"

 Hello!
root@sv01:~# echo -e "\\n Hello!"

 Hello!
root@sv01:~# echo -e "\\\n Hello!"
\n Hello!

मैं वहां पूरी तरह से खो गया हूं, इसलिए उदाहरण के लिए, तीन बैकस्लैश केवल एक बैक स्लैश क्यों देते हैं? मुझे उम्मीद है: पहले दो एक से बच जाएंगे, तीसरे से बचने के लिए कुछ भी नहीं मिलेगा, इसलिए यह एक स्लैश (पहले प्रयोग में रेखा) रहेगा, लेकिन क्या हो रहा है कि तीसरा सिर्फ गायब हो गया है।
मुझे चार में से एक बैकस्लैश क्यों मिल रहा है \\\\ Hello? मुझे उम्मीद है कि प्रत्येक जोड़ी एक बैक स्लैश -> दो बैकस्लैश देगी।

और मुझे अंतिम केस में तीन बैकस्लैम की आवश्यकता क्यों है \ n बच निकलने के लिए? भागने की पृष्ठभूमि में क्या हो रहा है? और यह कैसे \\nमामले से अलग है ?

पिछली पंक्तियों में जो चल रहा है, उसके बारे में किसी भी स्पष्टीकरण की मैं सराहना करता हूं।


echo -eव्यवहार किसी भी तरह से परिभाषित नहीं है - pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html देखें । आउटपुट पूरी तरह से कार्यान्वयन-परिभाषित है यदि इनपुट में कहीं भी शाब्दिक बैकस्लैश है, और एकमात्र अनुमत विकल्प है -n(इसका मतलब है कि मानकों-अनुरूप कार्यान्वयन का इसके आउटपुट पर echo -eप्रिंट होगा -e)।
चार्ल्स डफी

... यहां तक ​​कि अगर आप 100% सुनिश्चित हैं कि आपका शेल बश है, तब भी echo -e सुरक्षित नहीं है: echoमानक के अनुसार व्यवहार करेगा यदि दोनों posixऔर xpg_echoरनटाइम विकल्प सक्षम हैं, या यदि समान बिल्ड-टाइम विकल्पों के साथ संकलित किया गया है। इसके printfबजाय उपयोग करने के लिए सुरक्षित अभ्यास है - ऊपर दिए गए लिंक के आवेदन पत्र और राष्ट्रीय अनुभागों को देखें कि कैसे printfप्रतिस्थापन के रूप में कार्य करना है echo
चार्ल्स डफी

जवाबों:


28

इसका कारण bashऔर echo -eसंयुक्त है। सेman 1 bash

एक गैर-उद्धृत बैकस्लैश ( \) भागने का पात्र है। यह अपवाद के अपवाद के साथ अगले चरित्र के शाब्दिक मूल्य को संरक्षित करता है <newline>। [...]

दोहरे उद्धरण चिह्नों में पात्रों संलग्न उद्धरण के भीतर सभी पात्रों का शाब्दिक मूल्य को बरकरार रखता है, के अपवाद के साथ $, `, \, [...] बैकस्लैश अपनी विशेष अर्थ केवल जब निम्नलिखित पात्रों में से एक के बाद बरकरार रखती है: $`, ", \, या <newline>

मुद्दा यह है: डबल उद्धृत बैकलैश हमेशा विशेष नहीं होता है।

echoसामान्य रूप से विभिन्न कार्यान्वयन हैं , यह बिल्ट इन है bash; यहाँ महत्वपूर्ण बात यह व्यवहार है:

यदि -eप्रभाव में है, तो निम्नलिखित अनुक्रमों को मान्यता दी गई है:
\\
बैकस्लैश
[…]
\n
नई पंक्ति

अब हम डिकोड कर सकते हैं:

  1. echo -e "\ Hello!"- कुछ खास नहीं bash, कुछ खास नहीं echo; \रहता है।
  2. echo -e "\\ Hello!"- पहला दूसरे का शाब्दिक इलाज करने के लिए \कहता bashहै \; echoहो जाता है \ Hello!और ऊपर के रूप में कार्य करता है।
  3. echo -e "\\\ Hello!"- पहला दूसरे का शाब्दिक इलाज करने के लिए \कहता bashहै \; echoहो जाता है \\ Hello!और (क्योंकि -e) यह पहचानता \\है \
  4. echo -e "\\\\ Hello!"- पहला दूसरे का शाब्दिक इलाज करने के लिए \कहता bashहै \; तीसरा चौथे के बारे में भी ऐसा ही कहता है; echoहो जाता है \\ Hello!और (क्योंकि -e) यह पहचानता \\है \
  5. echo -e "\\\\\ Hello!"- पहला दूसरे का शाब्दिक इलाज करने के लिए \कहता bashहै \; तीसरा चौथे के बारे में भी ऐसा ही कहता है; आखिरी कोई खास नहीं है; echoहो जाता है \\\ Hello!और (क्योंकि -e) यह प्रारंभिक के \\रूप में पहचानता है \, अंतिम \बरकरार रहता है।

और इसी तरह। जैसा कि आप देख सकते हैं, लगातार चार तक बैकस्लैश एक परिणाम देते हैं। इसलिए आपको तीन पाने के लिए उनमें से कम से कम (नौ) की जरूरत है। 9 = 4 + 4 + 1।

अब इसके साथ \n:

  1. echo -e "\n Hello!"- कुछ खास नहीं है bash, इको एक ही तार मिलता है और (क्योंकि -e) यह \nएक नई रेखा के रूप में व्याख्या करता है।
  2. echo -e "\\n Hello!"- के रूप में bashव्याख्या ; हो जाता है और परिणाम ऊपर के रूप में ही है।\\\echo\n Hello!
  3. echo -e "\\\n Hello!"- bashप्रारंभिक \\रूप में व्याख्या करता है \; echoहो जाता है \\n Hello!और (क्योंकि -e) यह \\एक शाब्दिक के रूप में व्याख्या करता है \जिसे मुद्रित करने की आवश्यकता होती है।

परिणाम के साथ अलग होगा 'बजाय "(अलग होने के कारण bashव्यवहार) या बिना -e(अलग echoव्यवहार)।


1
आपका बहुत बहुत धन्यवाद! तो दो भागने वाले कदम हैं, जो कि मार के द्वारा किया गया कदम है, और दूसरा जो -eपहले से ही चलाए गए पाठ को देखते हैं, क्या वह सही है? अगर यह सही है, तो यह भ्रम को दूर करता है। क्या आप बता सकते हैं कि sedव्यवहार कैसा है? भागने की तकनीक में इसका अपना निर्माण होता है? तो मेरा मतलब है कि यह प्रतिध्वनि की तरह व्यवहार करता है -e?
मोहम्मद नौरेलिन

2
@MohammedNoureldin हाँ, दो चरण हैं। आपका मूल प्रश्न ठीक है क्योंकि यह है, चलो इसे अधूरा नहीं बनाते हैं sed। आप एक और सवाल पूछ सकते हैं ( sedकेवल के बारे में ), बस पहले अपना खुद का शोध करें।
कामिल मैकियोरोव्स्की

3
@MohammedNoureldin sedसमान मूल सिद्धांतों का पालन करेगा: bash कमांड लाइन की व्याख्या उसके नियमों, पार्सिंग (और शायद हटाने) उद्धरणों और पलायन के अनुसार करेगा। उस का परिणाम पारित हो जाता है sed, जो अपने भागने के नियमों के अनुसार इसकी व्याख्या करता है। BTW, आप इसमें एकल-उद्धृत स्ट्रिंग का उपयोग करके इसे सरल कर सकते हैं bash, क्योंकि इसमें एनी बचने की व्याख्या नहीं की गई है (bash द्वारा) - bash एकल-कोट्स को हटाता है, और जो उनके अंदर होता है उसे सीधे कमांड में भेजता है।
गॉर्डन डेविसन

मुझे अभी भी echo -e "\\\n Hello!"मामले में एक छोटी सी समस्या है । यहां बैश भागने से करेगा, और यह बन जाएगा \\n, फिर -eपरिणामी दो बैकस्लैश से बच जाएगा \\nऔर फिर वे बन जाएंगे \n। अब कौन \nइसे नई लाइन बनाने की व्याख्या करता है? आम तौर पर, के मामले में echo -e "\n Hello!", बैश कुछ नहीं करता है, और नई लाइन के रूप में -eव्याख्या \nकरता है। लेकिन पहले उल्लेखित स्थिति में व्याख्या करने से पहले व्याख्या की प्रक्रिया की गई थी \n। आप समझा सकते हैं कि कृपया?
मोहम्मद नौरेलिन

1
ठीक है मेरी गलती है, मैं 2 दिनों के लिए उनकी रातों के बारे में पढ़ रहा हूं, इसलिए जाहिर तौर पर मैंने मामलों को मिलाना शुरू कर दिया, मेरा मानना ​​है कि मुझे कुछ और मिला sedजिसमें कल रात मुझे उलझन हुई (शायद मैंने कल कुछ गलत किया था), लेकिन अब मैं फिर से साथ एक ही करने की कोशिश की echo -eऔर sedहै, और मैं अपवादित, धन्यवाद के रूप में एक ही बात मिल गया है!
मोहम्मद नौरेलिन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.