सिर्फ कुसलानंद के ठीक जवाब के ऊपर एक अतिरिक्त नोट ।
echo run after_bundle
ठीक है क्योंकि उन 3 तर्कों में से कोई भी वर्ण उन echo
वर्णों को सम्मिलित नहीं करता है जो शेल के लिए विशेष हैं।
और (अतिरिक्त बिंदु जो मैं यहां बनाना चाहता हूं) कोई सिस्टम लोकेल नहीं है जहां उन बाइट्स उन अक्षरों में अनुवाद कर सकें जो शेल के लिए विशेष हैं।
उन सभी पात्रों में हैं जो POSIX पोर्टेबल चरित्र सेट को कॉल करते हैं । उन वर्णों को मौजूद होना चाहिए और POSIX system and पर सभी वर्ण सेटों में समान कूटबद्ध किया जाना चाहिए।
ताकि कमांड लाइन की व्याख्या स्थानीय लोगों की परवाह किए बिना की जाएगी।
अब, यदि हम उस पोर्टेबल वर्ण सेट के बाहर के वर्णों का उपयोग करना शुरू करते हैं, तो उन्हें खोलना एक अच्छा विचार है, भले ही वे शेल के लिए विशेष न हों, क्योंकि एक अन्य लोकेल में, उन्हें बनाने वाले बाइट्स की व्याख्या अलग-अलग वर्णों के रूप में की जा सकती है जो बन सकते हैं खोल के लिए विशेष। ध्यान दें कि यह आप का उपयोग कर रहे हैं echo
या किसी अन्य कमांड, समस्या के साथ नहीं है, echo
लेकिन कैसे खोल अपने कोड पार्स करता है।
उदाहरण के लिए UTF-8 में:
echo voilà | iconv -f UTF-8 -t //TRANSLIT
यह à
0xc3 0xa0 के रूप में एन्कोडेड है। अब, यदि आपके पास शेल स्क्रिप्ट में कोड की एक पंक्ति है और शेल स्क्रिप्ट को एक उपयोगकर्ता द्वारा उपयोग किया जाता है, जो एक लोकेल का उपयोग करता है, जिसका चार्ट UTF-8 नहीं है, तो वे दो बाइट्स बहुत भिन्न वर्ण बना सकते हैं।
उदाहरण के लिए, एक fr_FR.ISO8859-15
स्थानीय भाषा में, मानक सिंगल-बाइट वर्णसेट का उपयोग करते हुए एक सामान्य फ्रांसीसी लोकेल, जो फ्रांसीसी भाषा को शामिल करता है (अंग्रेजी सहित अधिकांश पश्चिमी यूरोपीय भाषाओं के लिए उपयोग किया जाता है), कि 0xc3 बाइट को Ã
चरित्र के रूप में व्याख्या किया गया है और 0xa2 गैर के रूप में है अंतरिक्ष चरित्र को तोड़ना।
और NetBSD³ जैसी कुछ प्रणालियों पर, उस गैर-ब्रेकिंग स्पेस को एक खाली वर्ण के रूप में माना जाता है ( isblank()
यह सच है, यह मेल खाता है [[:blank:]]
) और गोले bash
इसलिए इसे अपने सिंटैक्स में एक टोकन सीमांकक के रूप में मानते हैं।
इसका मतलब है कि तर्क के echo
साथ चलने के बजाय $'voil\xc3\xa0'
, वे इसे $'voil\xc3'
तर्क के रूप में चलाते हैं , जिसका अर्थ है कि यह voilà
सही तरीके से प्रिंट नहीं होगा ।
यह बिग 5, बिग5-एचकेएससीएस, GB18030, GBK की तरह चीनी वर्ण सेट जो कई पात्रों जिसका एन्कोडिंग के रूप में समान कूट शामिल है के साथ एक बहुत खराब हो जाता है |
, `
, \
(यह भी है कि ऊटपटांग SJIS (सबसे खराब नाम के लिए), माइक्रोसॉफ्ट कांजी उर्फ, सिवाय ¥
इसके बजाय यह है \
, लेकिन अभी भी \
अधिकांश उपकरणों के रूप में माना जाता है क्योंकि यह 0x5c के रूप में एन्कोडेड है)।
उदाहरण के लिए, यदि एक zh_CN.gb18030
चीनी लोकेल में, आप एक स्क्रिप्ट लिखते हैं जैसे:
echo 詜 reboot
वह स्क्रिप्ट 詜 reboot
GB18030 या GBK का उपयोग कर एक लोकल में आउटपुट करेगा 唰 reboot
, BIG5 या BIG5-HKSCS का उपयोग करते हुए, लेकिन ASCII या ISO8859-15 या UTF-8 का उपयोग करते हुए एक लोकेल में, reboot
चलाने का कारण होगा क्योंकि GB18030 एन्कोडिंग का 詜
0xd4 0x7c है और 0x7c |
ASCII का एन्कोडिंग है इसलिए हम रनिंग को समाप्त करते हैं:
echo �| reboot
(यह कि का प्रतिनिधित्व हालांकि 0xd4 बाइट को लोकेल में प्रस्तुत किया गया है)। uname
इसके बजाय कम हानिकारक का उपयोग करके उदाहरण reboot
:
$ echo $'echo \u8a5c uname' | iconv -t gb18030 > myscript
$ LC_ALL=zh_CN.gb18030 bash ./myscript | sed -n l
\324| uname$
$ LC_ALL=C bash ./myscript | sed -n l
Linux$
( uname
चलाया गया था)।
इसलिए मेरी सलाह होगी कि उन सभी तारों को उद्धृत किया जाए, जिनमें पोर्टेबल चरित्र सेट के बाहर के पात्र हों।
हालांकि ध्यान दें, चूंकि की एन्कोडिंग \
और `
उन पात्रों में से कुछ की एन्कोडिंग में पाए जाते हैं, यह बेहतर नहीं उपयोग करने के लिए है \
या "..."
या $'...'
(अंदर जो `
और / या \
अभी भी विशेष कर रहे हैं), लेकिन '...'
बजाय पोर्टेबल वर्ण सेट के बाहर पात्रों उद्धृत करने के लिए।
मुझे ऐसी किसी भी प्रणाली के बारे में पता नहीं है, जिसमें एक स्थान है जहां चारसेट का कोई भी चरित्र है ( '
निश्चित रूप से स्वयं के अलावा ) जिसकी एन्कोडिंग में एन्कोडिंग है '
, इसलिए उन्हें '...'
निश्चित रूप से सबसे सुरक्षित होना चाहिए।
ध्यान दें कि कई गोले भी $'\uXXXX'
यूनिकोड कोड बिंदु के आधार पर वर्णों को व्यक्त करने के लिए एक संकेतन का समर्थन करते हैं । जैसे गोले में zsh
और bash
, चरित्र को लोकेल के चारसेट में एन्कोड किया गया होता है (हालांकि उस चरित्र में अप्रत्याशित व्यवहार नहीं हो सकता है अगर उस चरित्र में ऐसा नहीं है)। इससे आप अपने शेल कोड में गैर-एएससीआईआई अक्षर डालने से बच सकते हैं।
तो ऊपर:
echo 'voilà' | iconv -f UTF-8 -t //TRANSLIT
echo '詜 reboot'
या:
echo $'voil\u00e0'
echo $'\u8a5c reboot'
(चेतावनी के साथ यह स्क्रिप्ट को तोड़ सकता है जब उन स्थानों पर चलाए जा सकते हैं जिनमें वे वर्ण नहीं हैं)।
या बेहतर है, क्योंकि \
यह भी विशेष echo
(या कम से कम कुछ echo
कार्यान्वयन, कम से कम यूनिक्स के अनुरूप हैं):
printf '%s\n' 'voilà' | iconv -f UTF-8 -t //TRANSLIT
printf '%s\n' '詜 reboot'
(ध्यान दें कि \
पहले तर्क में भी विशेष है printf
, इसलिए गैर-एएससीआईआई पात्रों को वहां से बचना बेहतर होता है, क्योंकि उनमें एन्कोडिंग हो सकती है \
)।
ध्यान दें कि आप भी कर सकते हैं:
'echo' 'voilà' | 'iconv' '-f' 'UTF-8' '-t' '//TRANSLIT'
(यह ओवरकिल होगा लेकिन अगर आप यह सुनिश्चित नहीं कर पा रहे हैं कि पोर्टेबल कैरेक्टर सेट में कौन से अक्षर हैं तो आप निश्चित नहीं हैं)
यह भी सुनिश्चित करें कि `...`
कमांड प्रतिस्थापन के प्राचीन रूप का उपयोग न करें (जो बैकस्लैश प्रसंस्करण के अन्य स्तर का परिचय देता है), लेकिन $(...)
इसके बजाय का उपयोग करें ।
¹ तकनीकी तौर पर, echo
यह भी करने के लिए तर्क के रूप में पारित हो जाता है echo
उपयोगिता (यह बताने के लिए कि यह कैसे लागू किया गया था), यह argv[0]
और argc
है, हालांकि अधिकांश गोले में आजकल 3 echo
builtin है, ताकि exec()
एक के /bin/echo
3 तर्कों की सूची के साथ फ़ाइल से प्रेरित है खोल। तर्कों की सूची पर विचार करना आम बात है क्योंकि दूसरे के साथ शुरू होने वाली ( argv[1]
से argv[argc - 1]
) के रूप में यह है कि कमांड मुख्य रूप से कार्य करते हैं।
Systems ja_JP.SJIS
FreeBSD सिस्टम के आकर्षक स्थानीय होने के लिए एक उल्लेखनीय अपवाद है जिसके वर्ण में \
न तो कोई ~
चरित्र है और न ही !
³ ध्यान दें कि जबकि कई सिस्टम (FreeBSD, Solaris, GNU वाले नहीं) हालांकि U + 00A0 को [[:blank:]]
UTF-8 स्थानों में मानते हैं, कुछ अन्य स्थानों में जैसे ISO8859-15 का उपयोग करने वाले लोग करते हैं, संभवतः इस तरह के मुद्दे से बचते हैं।