एक कमांड के स्टड के लिए एक चर के मूल्य को कैसे पारित किया जाए?


105

मैं एक शेल स्क्रिप्ट लिख रहा हूं, जो कुछ हद तक सुरक्षित होनी चाहिए अर्थात सुरक्षित डेटा को कमांड के मापदंडों के माध्यम से पारित नहीं करता है और अधिमानतः अस्थायी फ़ाइलों का उपयोग नहीं करता है। मैं एक चर को एक कमांड के स्टड में कैसे पारित कर सकता हूं? या, यदि यह संभव नहीं है, तो ऐसे कार्य के लिए अस्थायी फ़ाइलों का सही उपयोग कैसे करें?


क्या कोई हमलावर बदल सकता है $PATH? ताकि catप्रतिस्थापित किया जा सके/bin/cat "$@" | tee /attacker/can/read/this/file
12431234123412341234123

जवाबों:


74

कुछ सरल के रूप में:

echo "$blah" | my_cmd

7
अपने चर में रिक्त स्थान: echo "$blah"बेहतर है।
जोनाथन लेफ्लर

13
आइए देखें कि आप कैसे संभालते हैं blah=-n, blah=-e... printfइसके बजाय उपयोग करें । unix.stackexchange.com/questions/65803/…
कैमिलो मार्टिन

1
ऐसा लगता है कि यह नाजुक और त्रुटि-प्रवण होगा, नहीं?
थोरसुमोनर

20
6 साल, अगर मैं इस उत्तर को हटा सकता था (लेकिन मैं इसे स्वीकार नहीं कर सकता क्योंकि ...)
ओलिवर चार्ल्सवर्थ

1
@OliverCharlesworth, इसे उपयोग करने के लिए संपादित क्यों नहीं करता है printf '%s\n' "$blah"? उस एक परिवर्तन के साथ (कई त्रुटियों से बचने echoके विनिर्देश, जो स्टीफ़न उत्तम जवाब में विस्तार से में चला जाता है क्यों है printfकी तुलना में बेहतर echo? पर यूनिक्स और लिनक्स , या जिनमें से एप्लिकेशन उपयोग अनुभाग echoविनिर्देश अधिक संक्षिप्त पर छूता है) यह एक पूरी तरह से है उचित जवाब।
चार्ल्स डफी

192

बैशstdin में एक मान पास करना उतना ही सरल है:

your-command <<< "$your_variable"

हमेशा यह सुनिश्चित करें कि आप चर के चारों ओर भाव डालते हैं!

सतर्क रहें, कि यह शायद केवल में bashकाम करेगा और इसमें काम नहीं करेगा sh


39
Herestrings <<<उपलब्ध होने की गारंटी नहीं है, वे POSIX आधार में नहीं हैं, जहां तक ​​मुझे पता है। जब तक आपके केवल उन्हें चलाने में वे अपेक्षित हैं, तब तक वे काम करेंगे bash। मैं केवल इसका उल्लेख करता हूं, क्योंकि वे ओपी ने कहा कि 'खोल' विशेष रूप से 'बैश' नहीं है। हालाँकि उन्होंने सवाल को टैग किया था bash... इसलिए यह अभी भी एक स्वीकार्य जवाब है।
जेएम बेकर

हालांकि यह मामला हो सकता है, echoपाइप के निर्माण के कारण विधि का उपयोग करते समय संवेदनशील जानकारी अधिक आसानी से लीक होने की संभावना है । हेर्स्ट्रिंग कमांड को पूरी तरह से संसाधित किया जाएगा bash, हालांकि इस स्थिति में (जैसा कि नोट किया गया है) आपको बेहतर पता था कि यह आपके बैश पर काम करेगा, अन्यथा हेरस्ट्रेस का समर्थन नहीं करने के परिणामस्वरूप उत्पन्न कोई भी त्रुटि संदेश भी लीक जानकारी होगी।
स्टीवन लू

@StevenLu रुको, echoएक अंतर्निहित है। वहां कोई पाइप नहीं, है ना? यह यूनिक्स है, लेकिन यह इतना यूनिक्स नहीं हो सकता ।
कैमिलो मार्टिन

4
@StevenLu printf '%s\n' "$var"उसी परिणाम का उत्पादन करता है echo "$var"जैसे कि अगर, जैसे var=-en, और नहीं तोड़ा जाएगा , और इसके लिए bash की भी आवश्यकता नहीं है।
कैमिलो मार्टिन

1
यह भी ध्यान दें कि स्ट्रिंग के लिए एक नई पंक्ति यहाँ स्ट्रिंग में संलग्न है।
पीडीआर

19

ध्यान दें कि ' echo "$var" | commandऑपरेशन्स का मतलब है कि स्टैंडर्ड इनपुट लाइन (एस) तक सीमित है। यदि आप भी चाहते हैं कि टर्मिनल जुड़ा रहे, तो आपको कट्टर होना चाहिए:

{ echo "$var"; cat - ; } | command

( echo "$var"; cat -   ) | command

इसका अर्थ है कि पहली पंक्ति (सामग्री) सामग्री होगी, $varलेकिन बाकी catइसके मानक इनपुट को पढ़ने से आएगी । यदि कमांड बहुत ज्यादा फैंसी नहीं करता है (कमांड लाइन एडिटिंग चालू करने की कोशिश vimकरता है , या रन करता है) तो यह ठीक रहेगा। अन्यथा, आपको वास्तव में फैंसी प्राप्त करने की आवश्यकता है - मुझे लगता है expectया इसके डेरिवेटिव में से एक उपयुक्त होने की संभावना है।

कमांड लाइन अंकन व्यावहारिक रूप से समान हैं - लेकिन ब्रेसिज़ के साथ दूसरा अर्ध-बृहदान्त्र आवश्यक है जबकि यह कोष्ठक के साथ नहीं है।


( echo "$LIST"; cat - ) | sed 1qयह मेरे लिए काम करता है लेकिन जब मुझे इस स्क्रिप्ट को चलाना है तो मुझे ctrl d दबाना होगा?
गर्ट कुयकेन्स

हाँ; cat -ताकि आप टाइपिंग नियंत्रण-डी द्वारा EOF यह बताने के लिए की जरूरत है, EOF या बाधा जब तक कीबोर्ड से पढ़ने के लिए जारी है।
जोनाथन लेफलर

क्या ईओएफ के आसपास कोई रास्ता है? sed को बिल्ली की आवश्यकता है
Gert Cuykens

catयदि आपको टर्मिनल इनपुट नहीं चाहिए, तो आपको पहली पंक्ति में उपयोग नहीं करना है। या आप catकिसी फ़ाइल को सूचीबद्ध करने के लिए उपयोग कर सकते हैं । या ... यदि आप चाहते हैं कि कमांड टर्मिनल इनपुट को पढ़े, तो आपको यह बताना होगा कि यह इनपुट के अंत तक कब पहुंचा है। या आप उपयोग कर सकते हैं ( echo "$var"; sed /quit/q - ) | command; यह तब तक जारी रहता है जब तक कि आप 'छोड़' वाली लाइन टाइप नहीं करते। आप इसे कैसे संभालते हैं, इसके बारे में आप पूरी तरह से खोज कर सकते हैं। एक कार्यक्रम के पुराने शहरी किंवदंती से सावधान रहें जब उपयोगकर्ताओं ने इक्वाडोर के साथ काम करना शुरू कर दिया। वे राजधानी, क्विटो और प्रोग्राम से बाहर निकलने के नाम पर टाइप करेंगे।
जोनाथन लेफलर

ठीक है तुम कहते हो तो। लेकिन सिर्फ क्यों नहीं echo "$LIST" | sed 1q | ...? यह सब इस पर निर्भर करता है कि आप किस बारे में हैं। <<EOFअंकन फ़ाइल नीचे अपनी ही कहीं पर एक लाइन की शुरुआत में एक EOF से हो जाएगा। मैं इसका उपयोग नहीं करूंगा, मुझे लगता है - लेकिन मुझे अभी भी यकीन नहीं है कि आप क्या हासिल करना चाहते हैं। एक सरल echo "$LIST" | commandया echo $LIST | commandशायद व्यवहार में पर्याप्त होगा (और यह महत्वपूर्ण है कि आप दोनों के बीच के अंतर का महत्व जानते हैं)।
जोनाथन लेफलर

16

मुझे मार्टिन का उत्तर पसंद आया, लेकिन इसमें कुछ समस्याएं हैं जो चर में है। यह

your-command <<< """$your_variable"""

बेहतर है यदि आप चर शामिल हैं "या!


4
पर क्यों? इसके अलावा, मैं किसी भी समस्या को पुन: पेश नहीं कर सकता: foo1=-; foo2='"'; foo3=\!; cat<<<"$foo1"; cat<<<"$foo2"; cat<<<"$foo3"मेरे लिए ठीक काम करता है। वास्तव में तीनों "क्या करते हैं? AFAIK आप केवल एक खाली स्ट्रिंग प्रस्तुत कर रहे हैं और जोड़ रहे हैं।
phk

कुछ असली कोशिश करो। जैसे आपकी आज्ञा है ssh somehost। और आपका चर एक शेल स्क्रिप्ट है।
रॉबर्ट जैकब्स

16
(cat <<END
$passwd
END
) | command

catवास्तव में जरूरत नहीं है, लेकिन यह बेहतर कोड की संरचना करने में मदद करता है और आप अपने आदेश को इनपुट के रूप में कोष्ठक में अधिक आदेशों का उपयोग करने की अनुमति देता है।


लेकिन यह विधि आपको अपनी कमांड में कई लाइनें पास करने की अनुमति देती है और $passwd
पोल्टो

4
यह अब तक का सबसे अच्छा जवाब है जो पाइप या स्नूपिंग प्रक्रिया के लिए परिवर्तनीय सामग्री को लीक नहीं करता है।
user2688272

8

मार्टिन के जवाब के अनुसार, हियर स्ट्रिंग्स नामक एक बैश फीचर है (जो स्वयं अधिक व्यापक रूप से समर्थित यहाँ का एक संस्करण है )

http://www.gnu.org/software/bash/manual/bashref.html#Here-Strings

3.6.7 यहाँ स्ट्रिंग्स

यहाँ दस्तावेजों का एक प्रकार है, प्रारूप है:

<<< word

इस शब्द को इसके मानक इनपुट पर कमांड में विस्तारित और आपूर्ति की जाती है।

ध्यान दें कि यहां स्ट्रिंग्स केवल बैश दिखाई देंगी, इसलिए, सुवाह्य पोर्टेबिलिटी के लिए, आप शायद पोल्टो के उत्तर के अनुसार मूल हियर डॉक्यूमेंट्स फीचर के साथ बेहतर होंगे।

( cat <<EOF
$variable
EOF
) | cmd

या, उपरोक्त का एक सरल संस्करण:

(cmd <<EOF
$variable
EOF
)

जब तक आप इस पुनर्निर्देशित को अन्य आदेशों में नहीं रखना चाहते, तब तक आप छोड़ सकते हैं (और )


5

यह मजबूत और पोर्टेबल तरीका पहले ही टिप्पणियों में दिखाई दे चुका है। यह एक स्टैंडअलोन जवाब होना चाहिए।

printf '%s' "$var" | my_cmd

या

printf '%s\n' "$var" | my_cmd

टिप्पणियाँ:

  • यह echoयहां से बेहतर है , कारण यहां हैं: इससे बेहतर क्यों है ?printfecho
  • printf "$var"गलत है। पहला तर्क प्रारूप जहां विभिन्न दृश्यों की तरह है %sया \nकर रहे हैं व्याख्या की । चर को सही पास करने के लिए, इसे प्रारूप के रूप में व्याख्यायित नहीं किया जाना चाहिए।
  • आमतौर पर चर में नई सीमाएँ नहीं होती हैं। पूर्व कमांड (साथ %s) चर को पार करता है जैसा कि यह है। हालाँकि, पाठ के साथ काम करने वाले उपकरण एक अधूरी रेखा के बारे में उपेक्षा या शिकायत कर सकते हैं (देखें कि पाठ फ़ाइलों को एक नई पंक्ति के साथ क्यों समाप्त होना चाहिए? )। तो आप बाद वाली कमांड (साथ %s\n) चाहते हैं जो कि वैरिएबल के कंटेंट के लिए एक न्यूलाइन कैरेक्टर को जोड़ दे। गैर-स्पष्ट तथ्य:

    • यहां बैश ( <<<"$var" my_cmd) में स्ट्रिंग एक नई रूपरेखा को जोड़ता है।
    • कोई भी विधि जो किसी नई पंक्ति का परिणाम गैर-खाली स्टैण्ड में डालती है my_cmd, भले ही वह चर खाली या अपरिभाषित हो।

4

इसे इस्तेमाल करे:

echo "$variable" | command

लेकिन सामग्री $ चर नहीं दिखाएगा जैसे कि ps -uजब इको चल रहा है तो आउटपुट ?

2
नहीं, यह नहीं होगा। echoबिल्ट-इन है, इसलिए ps में दिखाने के लिए कोई प्रक्रिया नहीं है
unbeli

2
अपने चर में रिक्त स्थान: echo "$variable"बेहतर है।
जोनाथन लेफ्लर

यह सही है, बैश डबल स्पेस खाएंगे, होशियार गोले नहीं
अनबेली

-1

बस करो:

printf "$my_var" | my_cmd

यदि संस्करण में रिक्त स्थान नहीं हैं, तो उद्धरण छोड़ा जा सकता है।
अगर बाश का उपयोग कर रहे हैं तो आप भी कर सकते हैं:

echo -n "$my_var" | my_cmd

इको बिना एन का उपयोग करने से बचें क्योंकि यह अंत में एक अतिरिक्त लाइनब्रेक के साथ व्यवहार्य को पाइप करेगा।


1
काम नहीं करता है अगर $ my_var है %s, प्रिंटफ कुछ भी प्रिंट नहीं करेगा। my_var="%s"; printf "$my_var"; - शायद कोशिश करें printf "%s" "$my_var" | my_cmd ?
हन्सेन्रिक्रिक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.