शेल कमांड सबस्टीट्यूशन एक अनुगामी न्यूलाइन चार को क्यों धारण करता है?


25

निम्नलिखित उदाहरण के अनुसार, और मेरे हालिया प्रश्न के अनुसार , बैश में, अनुगामी न्यूलाइन चार कहां गया है? , मैं जानना चाहता हूं "क्यों" ऐसा होता है

  x="$(echo -ne "a\nb\n")" ; echo -n "$x" | xxd -p 
# Output is: 610a62 
# The trailing newline from the 'echo' command
#   has been "deleted" by Command Substitution

मुझे लगता है कि शेल एक्शन के लिए कुछ बहुत ही महत्वपूर्ण कारण होने चाहिए , अर्थात् कमांड सबस्टीट्यूशन, वास्तव में कमांड आउटपुट से कुछ डेटा को हटाना है जो इसे प्रतिस्थापित
कर रहा है ... लेकिन मैं इस के आसपास अपना सिर नहीं प्राप्त कर सकता, जैसा कि यह प्रतीत होता है यह क्या करना चाहिए की प्रतिपक्षी .. यानी। स्क्रिप्ट प्रक्रिया में वापस कमांड के आउटपुट को पास करने के लिए ... एक वर्ण को वापस पकड़ना मुझे अजीब लगता है, लेकिन मुझे लगता है कि इसके लिए एक समझदार कारण है ... मैं यह जानने का इच्छुक हूं कि वह कारण क्या है .. ।


जवाबों:


22

क्योंकि शेल मूल रूप से एक पूर्ण प्रोग्रामिंग भाषा होने का इरादा नहीं था।

\nकुछ कमांड आउटपुट से ट्रेलिंग को निकालना काफी मुश्किल है । हालाँकि, प्रदर्शन उद्देश्यों के लिए, लगभग सभी कमांड अपने आउटपुट को समाप्त कर देते हैं \n, इसलिए ... इसे निकालने का एक सरल तरीका है जब आप इसे किसी अन्य कमांड में उपयोग करना चाहते हैं। $()निर्माण के साथ स्वचालित निष्कासन चुना गया समाधान था।

तो, शायद आप इस प्रश्न को उत्तर के रूप में स्वीकार करेंगे:

\nयदि आप निम्नलिखित कमांड में स्वचालित रूप से नहीं किया गया था, तो क्या आप ट्रेलिंग को हटाने का एक सरल तरीका खोज सकते हैं ?

> echo The current date is "$(date)", have a good day!

ध्यान दें कि उद्धृत स्थान को रिक्त स्थान की मुंहतोड़ता को रोकने के लिए आवश्यक है जो स्वरूपित तिथियों में दिखाई दे सकते हैं।


1
अगर तुम जो कहोगे वह सच है, तो मैं बिल्कुल स्तब्ध रहूंगा। यदि shoptआपके वर्णित डिफ़ॉल्ट व्यवहार को बदलने के लिए कोई है , तो मुझे फिर से खुशी होगी ... मुझे यह सोचना मुश्किल है कि बैश / लिनक्स / यूनिक्स ऐसे महत्वपूर्ण फ़ंक्शन को "कैप्चरिंग स्टडआउट" के रूप में सिर्फ इसलिए प्रदूषित करेगा, क्योंकि dateउसके पास नहीं है a / without '\ n' विकल्प के साथ ... स्पष्ट फ़र्क यह होगा कि bash (या अन्य शेल) के shoptलिए यह है ... क्या आप किसी के बारे में जानते हैं? .. और क्या आपके पास कोई संदर्भ लिंक है जो व्हाट्सएप और व्हॉट्सएप पर इस तरह की बात करता है? ... और क्यों dateएक \ n विकल्प नहीं है .. यह चाहिए!
पीटर।

2
1979 में यूनिक्स के "7 वें संस्करण" में बॉर्न शेल के पहले संस्करण में कमांड प्रतिस्थापन दिखाई दिए । यह पहले से ही एक बड़ी क्रांति थी और मुझे लगता है (मैं पैदा नहीं हुआ था) कि किसी ने '\ n' को पीछे रखने की परवाह नहीं की या नहीं। हां, आप 10min से कम में मैनपेज पढ़ सकते हैं , और ऐसा लगता है कि तब तक कमांड प्रतिस्थापन के बारे में कुछ भी नहीं बदला है। पसंदीदा $()वैकल्पिक सिंटैक्स को छोड़कर ।
स्टेफेन जिमेनेज

धन्यवाद .. मैंने सोचा कि यह एक विरासत मुद्दा हो सकता है, और यह निश्चित रूप से इस तथ्य को आकार दे रहा है कि मैं अपने कमांड सबस्टीट्यूशंस को अधिक ध्यान से देखना शुरू करूंगा। आज तक मैं एक प्रार्थना पर एक पंख से बच रहा होगा .. मैंने जिन "रहस्यमय घटनाओं" का सामना किया है उनमें से कुछ अब समझ में आने लगे हैं ... ... तो आपकी "तारीख" के उल्टे मामले में, अगर मैं अपना अनुगामी \ n रखना चाहता हूँ, मुझे कुछ इस तरह से कोड करना होगा :( { echo -n "The current date is "; var="$(date; echo -e x)"; var="${var%x}"; echo -n "$var"; echo ", have a good day!"; }.. तो ऐसा ही हो :)
पीटर।

पुनश्च मेरी उपरोक्त टिप्पणी: बेशक, बस dateकाम करेगा, लेकिन मैं सिर्फ किसी भी आदेश dateका एक उदाहरण के रूप में इस्तेमाल किया ..
पीटर।

तिथि के बारे में आपका 'सवाल' मेरी समझ के प्रति सबसे मजबूत प्रोम था 'क्यों' कमांड सब्स्टीट्यूशन यह क्या करता है, इसलिए यह मेरे प्रश्न का 'सबसे अच्छा' उत्तर है ... और मुझे निश्चित रूप से अन्य अच्छे उत्तरों की भी आवश्यकता थी ..
पीटर।

19

यह मानक का हिस्सा है :

खोल क्रियान्वित करते हुए आदेश प्रतिस्थापन का विस्तार करेगा आदेश एक subshell वातावरण में (देखें शैल निष्पादन पर्यावरण और आदेश प्रतिस्थापन (के पाठ की जगह) आदेश आदेश के मानक उत्पादन के साथ साथ साथ संलग्न "$ ()" या backquotes), को हटाने प्रतिस्थापन के अंत में एक या अधिक <newline> s के क्रम।

बेशक, मानक शायद इस तरह लिखा जाता है क्योंकि यह कैसे kshया कुछ किया है, लेकिन यह मानक है, और यह प्रलेखित व्यवहार है। यदि आप इसे पसंद नहीं करते हैं, तो पर्ल या कुछ और का उपयोग करें जो आपको अनुगामी नईलाइन्स रखने देगा।


एक अच्छा सारांश .. धन्यवाद .. और लिंक निश्चित रूप से मदद की
पीटर।

4
मानक ऐसा ही है क्योंकि बोर्न शेल ने ऐसा ही किया और तब से हर दूसरे शेल में।
गिल्स एसओ- बुराई को रोकें '

6

खैर, यह मेरे लिए समझ में आता है। नई कमांड केवल पहले स्थान पर है, सामान्य कमांड आउटपुट में, ताकि कमांड नई लाइन पर पूरा होने के बाद शीघ्र दिखाई दे। न्यूलाइन ज्यादातर मामलों में मूल आउटपुट का हिस्सा नहीं है, यह स्क्रीन को साफ करने के लिए है। जब आप एक कमांड से आउटपुट पार्स कर रहे होते हैं, तो अंत में न्यूलाइन आमतौर पर परेशान करने वाली होती है। wcकमांड पाठ की 2 लाइनें क्यों आउटपुट करता है ? ओह, यह नहीं है, यह एक के बाद एक newline outputs। जब आप पार्स wcकरते हैं तो आप इस तथ्य के बारे में चिंता नहीं करना चाहते हैं कि आउटपुट की 2 लाइनें हैं - वास्तव में नहीं हैं, केवल एक ही है।


@EightBitTony: मेरा प्रश्न किसी भी तरह से टर्मिनल में कुछ प्रदर्शित करने से संबंधित नहीं है .. यह काफी सीधे आगे है। अगर वहाँ एक प्रदर्शन करने के लिए newline है, तो यह newline प्रदर्शित करेगा .. यहाँ सवाल में बात यह है कि \nमूल में हैstdout में कमांड प्रतिस्थापन द्वारा हटा दिया जाता है। अर्थात। मेरे मूल डेटा (बहुत महत्वपूर्ण डेटा) में नई कड़ियों को हटा दिया गया है, तब भी जब डेटा "उद्धरण" में लिपटा हुआ है। मैं यथोचित रूप से समझता हूं कि वर्ड स्प्लिटिंग कैसे और क्यों काम करता है, लेकिन मुझे इस बात का बिलकुल भी अंदाजा नहीं है कि कमांड सब्स्टीट्यूशन केवल नई सुर्खियां और केवल अनुगामी क्यों हैं।
पीटर।

1
आपने जो कुछ भी कहा है वह मेरे विचार को बदल देता है। अधिक बार नहीं, किसी भी आउटपुट में अंतिम न्यूलाइन पूरी तरह से प्रदर्शन उद्देश्यों के लिए होती है, डेटा के हिस्से के रूप में नहीं।
EightBitTony

मैं आपके विचार से सहमत हैं, और ... सब साथ है हाँ उत्पादन के अंत में नई पंक्ति है सुविधा के लिए ... लेकिन मेरी समस्या यह है कि कोई लेना देना नहीं है ... मैं पूछ रहा हूँ: क्यों कमान प्रतिस्थापन जबरन इसे हटाने करता है ? ... ये दो अलग-अलग मुद्दे हैं .. शायद मेरा सवाल यह होना चाहिए: क्या वर्कअराउंड में बनाया गया है? । क्योंकि इस मुद्दे के लिए कोड करने के लिए एक अनुगामी डमी चार जोड़कर, बेकार है! ... मैं इसे करूँगा अगर मुझे करना है, लेकिन यह पहली बार है जब मुझे बैश द्वारा (और मैं सदमे की स्थिति में हूँ) :) यह बहुत अच्छी तरह से करता है ...
पीटर।

जैसा कि एक अन्य उत्तर में बताया गया है, यह मानक का हिस्सा है। मेरे लिए, मुझे लगता है कि यह इस तरह से करता है क्योंकि जब आप डेटा पोस्ट-प्रोसेस करते हैं तो आप केवल डेटा देखना चाहते हैं, न कि सुविधाजनक न्यूलाइन। ऐसा इसलिए है क्योंकि शेल से आपको पाइप में डेटा को संभालने की उम्मीद है , और न्यूलाइन डेटा नहीं है। किसी भी अधिक और हमें इस पर चर्चा करने की आवश्यकता है।
EightBitTony

धन्यवाद .. मैं अब अच्छी तरह से विचार मिल गया है .. यह कमांड प्रतिस्थापन का एक मामला लगता है बस अनुगामी newlines छोड़ने के बजाय उन्हें maintaing के बजाय झुकता है .. उस कदम में कुछ ज्ञान होना चाहिए जो मुझे याद है "लगा "अभी तक, लेकिन मुझे लगता था कि फ़ाइल नाम में सभी लो-केस पत्रों का अत्यधिक लोकप्रिय उपयोग थोड़ा अजीब / अनावश्यक था, लेकिन मैं दूसरे दिन बस सोच रहा था कि यह वास्तव में काफी आरामदायक प्रणाली है .. मैं शायद देखें (अधिक गहराई से) कमांड
सब्स्टीट्यूशन

1

मैं एक ही मुद्दे में चल रहा था, और उदाहरण के नीचे पाया। लगता है कि उद्धृत करने से स्थिति में मदद मिली, कम से कम यह मेरे लिए था:

http://tldp.org/LDP/abs/html/commandsub.html

dir_listing=`ls -l`
echo $dir_listing     # unquoted

# Expecting a nicely ordered directory listing.

# However, what you get is:
# total 3 -rw-rw-r-- 1 bozo bozo 30 May 13 17:15 1.txt -rw-rw-r-- 1 bozo
# bozo 51 May 15 20:57 t2.sh -rwxr-xr-x 1 bozo bozo 217 Mar 5 21:13 wi.sh

# The newlines disappeared.


echo "$dir_listing"   # quoted
# -rw-rw-r--    1 bozo       30 May 13 17:15 1.txt
# -rw-rw-r--    1 bozo       51 May 15 20:57 t2.sh
# -rwxr-xr-x    1 bozo      217 Mar  5 21:13 wi.sh

2
यहाँ क्या हो रहा है। मान लें कि आपके पास एक चर है $str, जिसमें स्ट्रिंग है "a b c"। आप पार कर लेते हैं $strकरने के लिए echoउद्धरण (बिना echo $str), echoप्राप्त होगा a, bऔर cअलग तर्क के रूप में तीन। आपका खोल बहस के बीच व्हाट्सएप की परवाह नहीं करता है। echoफिर उन तर्कों को हर एक को अलग करने वाले रिक्त स्थान के साथ प्रिंट करेंगे, ताकि आप प्राप्त करें "a b c"। यदि आप echoइसके चारों ओर के उद्धरणों के साथ चर को पास करते हैं ( echo "$str"), शेल इसे एक तर्क के रूप में देखता है और echoइसे इस तरह प्राप्त करता है, तो व्हॉट्सएप ध्वस्त नहीं होता है। यही बात newlines पर भी लागू होती है।

1
मूल पोस्टर में जो समस्या है, वह यह है कि उसके आदेशों की अनुगामी नईलाइन्स (बस बहुत अंतिम वाले) गायब हो रही हैं। जब तक -nध्वज को पारित नहीं किया जाता है, तब तक echoइसके आउटपुट में एक अनुगामी न्यूलाइन जोड़ा जाता है, इसलिए आपके उदाहरण में दोनों इकोस में नई सीमाएँ होती हैं। हालाँकि, यदि आप प्रयास करते हैं echo -n $dir_listingया echo -n "$dir_listing", आप देखेंगे कि कोई अनुगामी न्यूलाइन आसपास के उद्धरणों के साथ या उसके बिना मुद्रित नहीं है $dir_listing, जो बताता है कि समस्या कमांड प्रतिस्थापन के साथ है।

2
tldp शेल स्क्रिप्टिंग के बारे में जानने के लिए एक बुरी तरह से पुरानी जगह है। इसके बजाय वूल्श बैश विकी आज़माएं। mywiki.wooledge.org/BashGuide
वाइल्डकार्ड

-1

क्यों करता है echo "hello " (कोट्स के बिना) अंतरिक्ष को टटोलता है? IFS वर्णों के मान को शेल द्वारा सीमांकित के रूप में देखा जाता है, इसके बाद, अनुगामी वाले (जो कुछ भी परिसीमन नहीं करते हैं) निकाले जा रहे हैं। सराहनीय प्रतिस्थापन केवल उप-शेल में कमानों को निष्पादित करना सादा है, इसलिए यह उसी तर्क का अनुसरण करता है।


@Philomath: दोनों x="hello  "और x="hello     "खो देंगे सब उनके पीछे वाले स्पेस के माध्यम से प्रदर्शित कर रहे हैं echo $x... लेकिन केवल आखिरी कमान Substituton के न्यू लाइन खो दिया है।
पीटर।

अजीब है, मैं अपने बैश में कोई अंतर (XXD से यह सत्यापित) नहीं दिख रहा है
Philomath

मैं बस इस पर जाँच करता हूँ ... यह सभी नई रूपरेखाओं को हटा देता है ... जब मुझे यह आभास हुआ तो मैं IFS के साथ प्रयोग कर रहा था, तो चलिए उस एक को रद्द करते हैं :) .. लेकिन सवाल अभी भी बना हुआ है ... यह एक मौलिक हिस्सा है शब्द एक ही स्थान पर कई स्थानों को संघनित करने के लिए विभाजित होता है, और व्हाट्सएप से अग्रणी और अनुगामी को पूरी तरह से हटाने के लिए .. मैं यह समझ सकता हूं , लेकिन मैं निश्चित रूप से यह नहीं समझता कि कमांड सबस्टीट्यूशन के साथ, यह केवल स्ट्रिप्स \ n और सभी व्हाट्सएप के रूप में नहीं (के रूप में) शब्द बंटवारे के साथ), और क्यों केवल अनुगामी अंत? .. और सबसे ऊपर: "कमान प्रतिस्थापन" केवल आंशिक रूप से प्रतिस्थापित किया गया है .. क्यों?
पीटर।

4
IFSकमांड प्रतिस्थापन के अंत में स्ट्रिपिंग न्यूलाइन्स से कोई लेना-देना नहीं है।
गाइल्स का SO- बुराई पर रोक '
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.