मेरे पास एक सी प्रोग्राम है जो argv से कमांड लाइन तर्क पढ़ता है। क्या मेरे प्रोग्राम में कमांड लाइन तर्क के रूप में फ़ाइल की सामग्री को पुनर्निर्देशित करने के लिए एक पाइप बनाना संभव है? मान लीजिए मेरे पास एक फाइल है arguments.dat
इस सामग्री के साथ:
0 0.2 302 0
और मैं चाहता हूं कि मेरा कार्यक्रम कहलाए:
./myprogram 0 0.2 302 0
मैंने निम्नलिखित कोशिश की:
cat arguments.dat | ./myprogram
सफलता के बिना।
उत्तर:
जवाब के लिए 5 № 1अधिकांश गोले के साथ, आप फ़ाइल की सामग्री को कमांड लाइन में सम्मिलित कर सकते हैं $(<filename)
:
./myprogram $(<arguments.dat)
यदि आपका खोल इसका समर्थन नहीं करता है, तो पुराने तरीकों में से एक काम करेगा:
./myprogram $(cat arguments.dat)
./myprogram `cat arguments.dat` # need this one with csh/tcsh
(आप कमांड लाइन तर्क और फ़ाइल इनपुट के बीच अंतर जानते हैं, है ना? आप प्रोग्राम में पाइप कमांड लाइन तर्कों की अपेक्षा क्यों करेंगे?)
जवाब के लिए 11 № 2
xargs
आपका जवाब है
cat arguments.dat | xargs ./myprogram
या आसान:
xargs -a arguments.dat ./myprogram
अनुकूलित करने के कई तरीकों के लिए मैन्युअल जांचें xargs
। उदाहरण के लिए, आप शब्द के बजाए लाइन-दर-रेखा पढ़ सकते हैं, और आप अधिक जटिल प्रतिस्थापन में तर्कों का उपयोग कर सकते हैं।
जवाब के लिए 2 № 3
... जो कहने के लिए है: नीचे दिए गए उत्तर उन मामलों पर लागू होते हैं जहां यह स्वीकार्य नहीं होगा ./myprogram --first-argument "first value"
चुपचाप में बदलने के लिए ./myprogram --first-argument; ./myprogram "first value"
.
यदि आपके तर्क एक-से-एक-पंक्ति अक्षर हैं
यही है, अगर आपका इनपुट इस तरह दिखता है:
--first-argument
first value
--second-argument
second value
और आप इसे चलाने के लिए मतलब है:
./myprogram --first-argument "first value" --second-argument "second value"
... तो आपको उपयोग करना चाहिए (बैश 4.0 या बाद में):
readarray -t args <arguments.dat
./myprogram "${args[@]}"
... या (बैश 3.x के लिए भी):
args=( )
while IFS= read -r arg; do
args+=( "$arg" )
done <arguments.dat
./myprogram "${args[@]}"
यदि आपके तर्क उद्धरण के साथ प्रदान किए जाते हैं या उन्हें अलग करने के लिए भागते हैं
यही है, अगर आपकी फ़ाइल में कुछ ऐसा है (ध्यान दें कि न्यूलाइन और अनगिनत रिक्त स्थान समान रूप से व्यवहार करते हैं):
--first-argument "first value"
--second-argument "second value"
... और आप इसे चलाने के लिए मतलब है:
./myprogram --first-argument "first value" --second-argument "second value"
... तो आपको इसका उपयोग करना चाहिए:
args=( )
while IFS= read -r -d "" arg; do
args+=( "$arg" )
done < <(xargs printf "%s " <arguments.dat)
यदि आप अपने तर्क प्रारूप को नियंत्रित करते हैं
एनयूएल-सीमांकित मान का प्रयोग करें। यही है, फ़ाइल को इस प्रकार बनाएं:
printf "%s " "argument one" "argument two" >arguments.dat
... और इसे निम्नानुसार पार्स करें:
args=( )
while IFS= read -r -d "" arg; do
args+=( "$arg" )
done <arguments.dat
./myprogram "${args[@]}"
यह काम करेगा सब संभव तर्क मूल्य, यहां तक कि शाब्दिक न्यूलाइन, शाब्दिक उद्धरण, शाब्दिक बैकस्लाश, या अन्य गैर-मुद्रित पात्रों वाले भी। (शाब्दिक एनयूएलएस संभव नहीं है यूनिक्स कमांड लाइनों में, क्योंकि कमांड लाइन एनयूएल-समाप्त तारों से बना है; इस प्रकार, एनयूएल एकमात्र चरित्र है जो एक स्ट्रिंग में स्पष्ट रूप से अलग तर्कों के लिए उपयोग करने के लिए पूरी तरह से सुरक्षित है)।
यदि आमंत्रण में तर्कों को विभाजित करना वांछित है
वांछित परिणाम अगर यह उपधारा प्रासंगिक है(जब आपके फ़ाइल में अधिक तर्क होते हैं तो आपके प्रोग्राम के आमंत्रण के लिए पारित किया जा सकता है) कार्यक्रम के कई अलग-अलग आमंत्रण होते हैं, प्रत्येक को तर्कों का सबसेट प्राप्त होता है। यह मामलों का एक परिवार है जहां xargs
नौकरी के लिए सही उपकरण है।
यदि एक जीएनयू मंच पर, आप दौड़ना चाहते हैं xargs -a arguments.dat
stdin पुनर्निर्देशित करने के बजाय; हालांकि, यह बीएसडी xargs (मैकोज़ पर) के साथ समर्थित नहीं है, और इसलिए यहां प्रदर्शित नहीं किया गया है।
यदि आपके तर्क एक-से-एक-पंक्ति अक्षर हैं
जीएनयू xargs (अधिकांश लिनक्स प्लेटफॉर्म) के साथ:
xargs -d $"n" ./myprogram <arguments.dat
बीएसडी xargs के साथ (मैकोज़, फ्रीबीएसडी / ओपनबीएसडी / आदि):
xargs -0 ./myprogram < <(tr "n" " " <arguments.dat)
यदि आपके तर्क उद्धरण के साथ प्रदान किए जाते हैं या उन्हें अलग करने के लिए भागते हैं
xargs ./myprogram <arguments.dat
यदि आपने एनयूएल-सीमांकित इनपुट उत्पन्न किए हैं
xargs -0 ./myprogram <arguments.dat