मैं बैश का उपयोग करके किसी फंक्शन के आउटपुट को वेरिएबल में कैसे असाइन कर सकता हूं?


98

मेरे पास एक बश फ़ंक्शन है जो कुछ आउटपुट का उत्पादन करता है:

function scan {
  echo "output"
}

मैं इस आउटपुट को एक चर में कैसे निर्दिष्ट कर सकता हूं?

अर्थात। VAR = स्कैन (बेशक यह काम नहीं करता है - यह VAR को स्ट्रिंग "स्कैन" के बराबर बनाता है)


जवाबों:


146
VAR=$(scan)

बिल्कुल कार्यक्रमों के लिए उसी तरह।


3
मुझे पता चला कि जब मैंने "प्रतिध्वनि $ वार" की थी, तो नई कहानियां छीनी जा रही थीं। अगर इसके बजाय मैंने $ VAR का हवाला दिया, तो इसने नई कहानियों को संरक्षित किया।
ब्रेंट

2
यह 100% सही नहीं है। कमांड प्रतिस्थापन हमेशा नई सुर्खियों में आने वाली स्ट्रिप्स है।
बोनसाई

7
यह एक उपधारा बनाता है; क्या इसे उसी शेल में करने का कोई तरीका है?
सीमित प्रायश्चित

24

आप आदेशों / पाइपलाइनों में bash फ़ंक्शन का उपयोग कर सकते हैं क्योंकि आप अन्यथा नियमित कार्यक्रमों का उपयोग करेंगे। कार्य सब-सब्सक्रिप्शन और ट्रांसमिटिवली, कमांड सबस्टीट्यूशन के लिए भी उपलब्ध हैं:

VAR=$(scan)

ज्यादातर मामलों में आप जो परिणाम चाहते हैं, उसे प्राप्त करने के लिए कठिन तरीका है। मैं नीचे विशेष मामलों की रूपरेखा तैयार करूंगा।

अनुगामी अनुरक्षण Newlines:

कमांड सबस्टीट्यूशन के साइड इफेक्ट्स में से एक (आमतौर पर सहायक) साइड इफेक्ट यह है कि यह किसी भी संख्या में नए नंबर को पीछे छोड़ देगा। यदि कोई अनुगामी नईलाइन्स को संरक्षित करना चाहता है, तो कोई उप-आउटपुट के लिए एक डमी चरित्र को जोड़ सकता है, और बाद में इसे पैरामीटर विस्तार के साथ पट्टी कर सकता है।

function scan2 () {
    local nl=$'\x0a';  # that's just \n
    echo "output${nl}${nl}" # 2 in the string + 1 by echo
}

# append a character to the total output.
# and strip it with %% parameter expansion.
VAR=$(scan2; echo "x"); VAR="${VAR%%x}"

echo "${VAR}---"

प्रिंट (3 नए अंक रखे गए):

output


---

आउटपुट पैरामीटर का उपयोग करें: सबस्क्रिप्शन से परहेज (और नए सिरे को संरक्षित करना)

यदि फ़ंक्शन जो हासिल करने की कोशिश करता है, वह एक स्ट्रिंग को "v" लौटा देता है, जिसमें bash v4.3 और ऊपर के साथ, एक का उपयोग कर सकते हैं nameref। नामेरेफ़्स एक फ़ंक्शन को एक या अधिक चर आउटपुट पैरामीटर का नाम लेने की अनुमति देता है। आप एक nameref वैरिएबल को चीजें असाइन कर सकते हैं, और यह वैसा ही है जैसे कि आपने वैरिएबल को 'पॉइंट्स / रेफरेंस' में बदल दिया है।

function scan3() {
    local -n outvar=$1    # -n makes it a nameref.
    local nl=$'\x0a'
    outvar="output${nl}${nl}"  # two total. quotes preserve newlines
}

VAR="some prior value which will get overwritten"

# you pass the name of the variable. VAR will be modified.
scan3 VAR

# newlines are also preserved.
echo "${VAR}==="

प्रिंट:

output

===

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

ध्यान दें: यदि आपके फ़ंक्शन बैश बिल्डिंग्स पर बहुत अधिक भरोसा करते हैं, तो namerefs का उपयोग करना आपके प्रोग्राम के प्रदर्शन में बहुत सुधार कर सकता है, क्योंकि यह एक सबस्क्रिप्शन के निर्माण से बचता है जिसे कुछ समय बाद ही फेंक दिया जाता है। यह आम तौर पर अक्सर उपयोग किए जाने वाले छोटे कार्यों के लिए अधिक समझ में आता है, उदाहरण के लिए समाप्त होने वाले फ़ंक्शनecho "$returnstring"

यह प्रासंगिक है। https://stackoverflow.com/a/38997681/5556676


0

मुझे लगता है init_js को लोकल के बजाय डिक्लेयर का इस्तेमाल करना चाहिए!

function scan3() {
    declare -n outvar=$1    # -n makes it a nameref.
    local nl=$'\x0a'
    outvar="output${nl}${nl}"  # two total. quotes preserve newlines
}

localनिर्मित किसी भी विकल्प है कि स्वीकार करेंगे declarebuiltin को स्वीकार करेंगे। एक त्वरित परीक्षण से, यह भी दिखता है जैसे कि declare -nएक फ़ंक्शन स्कोप भी चर स्थानीय स्कोप देता है। ऐसा लगता है कि वे यहाँ विनिमेय हैं।
init_js 19
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.