2013-03-22 17 views
7

के साथ बैश प्रिंटफ मैं एक वेरिएबल प्रिंट करने में थोड़ा उलझन में हूं जिसमें बैश में एक नया लाइन प्रतीक होता है।नई लाइन

var="Age:\n20\ncolor:\nred" 
echo -e $var 
Age: 
20 
color: 
red 

यह काम कर रहा है, लेकिन बहुत से लोगों को कहना है कि विकल्प के साथ कि गूंज not portable और it is better to use printf है।

मैंने कभी भी प्रिफ का उपयोग नहीं किया। इको कमांड का अनुकरण करने के लिए मैनुअल के अनुसार:

printf '%s\n' "$var" 
Age:\n20\ncoloe:\nred 

लेकिन यह चर के अंदर \ n पार्स नहीं करता है। मैनुअल में आमतौर पर यह उदाहरण होता है:

printf "Surname: %s\nName: %s\n" "$SURNAME" "$LASTNAME" 

लेकिन यह मेरा मामला नहीं है और मेरे दृष्टिकोण से इसका उपयोग करने में सहज नहीं है।

printf "$ वर \ n"

यह पोर्टेबल है: मैं बस टाइपिंग है कि मैं इस का उपयोग कर सकते द्वारा पता चला? यदि मैं मेल कमांड पर $ var पास करता हूं तो क्या यह नई लाइन ब्रेक बचाएगा?

printf "$var\n" | mail -s subj [email protected] 
+0

'printf' के साथ समस्या यह है कि यह एक खोल कुछ गोले (बैश और ksh93), लेकिन दूसरों पर एक बाहरी प्रक्रिया पर निर्मित है (श, ksh88, csh) । इसलिए पुराने शैल पर 'printf' का उपयोग करके आप प्रोग्राम को धीमा कर सकते हैं, इस पर निर्भर करते हुए कि आप कितनी बार इसका इस्तेमाल करते हैं। – cdarke

उत्तर

16

printf के %b फॉर्मेट स्पेसिफायर विशेष रूप से echo -e को बदलने के लिए चाहिए था (वास्तव में, जिसके द्वारा डिफ़ॉल्ट। -e तर्कों की विशेष व्याख्या के लिए कहता है echo को XSI विस्तार निर्दिष्ट न किया गया और POSIX द्वारा अस्वीकृत है।), और लगभग $'...' और printf पर प्रारूप स्ट्रिंग तर्क से कुछ अंतर सहित लगभग हर तरह से समान है।

$ (var='Age:\n20\ncolor:\nred'; printf '%b\n' "$var") 
Age: 
20 
color: 
red 

आप आम तौर पर प्रारूप स्ट्रिंग में चर का विस्तार जब तक अपने कार्यक्रम सही मूल्य को नियंत्रित करता है से बचना चाहिए और यह विशेष रूप से एक प्रारूप स्ट्रिंग होना करने का इरादा है। printf के -v विकल्प के कारण विशेष रूप से आपके अंतिम उदाहरण में बैश में काफी खतरनाक होने की संभावना है।

# Bad! 
var='-v_[$(echo "oops, arbitrary code execution" >&2)0]' 
printf "$var" foo 

यह आमतौर पर %b से बचने के लिए जब तक आप एक विशेष पोर्टेबिलिटी आवश्यकता है अच्छी आदत है। शाब्दिक डेटा के बजाय एक चर में भागने वाले कोड को संग्रहीत करना कोड और डेटा को अलग करने के सिद्धांतों का उल्लंघन करता है। ऐसे संदर्भ हैं जिनमें यह ठीक है, लेकिन आमतौर पर $'...' उद्धरण का उपयोग करके मान असाइन करना बेहतर होता है, जो POSIX के अगले संस्करण के लिए निर्दिष्ट है, और लंबे समय तक बैश और अधिकांश केएस स्वादों में उपलब्ध है।

x=$'foo\nbar'; printf '%s\n' "$x" # Good 
x=(foo bar); printf '%s\n' "${x[@]}" # Also good (depending on the goal) 
x='foo\nbar'; printf '%b\n' "$x"  # Ok, especially for compatibility 
x='foo\nbar'; printf -- "$x"   # Avoid if possible, without specific reason 
+0

विस्तृत उत्तर के लिए धन्यवाद। – idobr

+0

@ormaaj: मैंने किसी को देखा है (आप?) सुविधाओं का उल्लेख है जो पहले POSIX के अगले संस्करण में जोड़ा जाएगा; क्या इसका सार्वजनिक रूप से दृश्य ड्राफ्ट है? बस उत्सुक। – chepner

+0

@chepner ड्राफ्ट चश्मा सूची ग्राहकों के लिए उपलब्ध हैं। 2008 टीसी 1 पहले से ही अंतिम रूप दिया गया है और अब किसी भी समय बाहर होना चाहिए, हालांकि [यह] (http://austingroupbugs.net/view.php?id=249) (और अन्य "फीचर" परिवर्तन) कम से कम तब तक नहीं आएंगे मुद्दा 7. कोई भी [gmane] (http: //dir.gmane पर सूची अभिलेखागार पढ़ सकता है।org/gmane.comp.standards.posix.austin.general), या बग ट्रैकर खोजें। सिद्धांत रूप में, यदि आपके पास सही उपकरण हैं, तो आप बग ट्रैकर diffs से चीजों की वर्तमान स्थिति बना सकते हैं (मैंने इसका प्रयास नहीं किया है)। – ormaaj