2014-07-10 7 views
7

से एक स्ट्रिंग लौटें मुझे कॉलर स्पेस पर वापस जाने के लिए गतिशील रूप से निर्मित स्ट्रिंग को वापस करने के लिए एक बैश फ़ंक्शन की आवश्यकता है। यानी,बैश: बैश फ़ंक्शन

makeName() 
{ 
    echo "Enter Ext: " 
    read ext 
    return "$fileName.$1.$ext.log" 
} 


echo -n "Enter fileName:" 
read fileName 

name1=makeName "type1" 
name2=makfName "type2" 

तो मैं एक ही आधार फ़ाइल नाम के साथ दो अलग-अलग फ़ाइल नाम मिल सकता है। मैं इस तरह कर रही है की कोशिश करता,

# echo $(makeName "type1") 

लेकिन इस कोड को कहीं बाहर किसी भी कारण या त्रुटि के साथ मारा गया है। मैं उम्मीद करता हूं कि यह उस प्रो के साथ किसी प्रकार का I/O स्वीकार करे। ऐसा नहीं हो रहा है।

उत्तर

12

return बयान bash द्वारा इस्तेमाल किया एक अंकीय मान वापस जाने के लिए के रूप में एक स्थिति कोड बुला समारोह से $? के माध्यम से प्राप्त किया जा करने के लिए प्रयोग किया जाता है। आप एक स्ट्रिंग वापस नहीं कर सकते हैं। भी

आप एक विशेष वैश्विक चर का उपयोग कर सकते हैं या तो के रूप में @konsolebox द्वारा प्रस्तावित या देखें, echo अपने समारोह के अंदर वापसी मान, और जब फ़ंक्शन को कॉल आदेश प्रतिस्थापन का उपयोग :

makeName() 
{ 
    echo "$fileName.$1.log" 
} 


echo -n "Enter fileName:" 
read fileName 

name1=$(makeName "type1") 
name2=$(makeName "type2") 

echo $name1 
echo $name2 

[अद्यतन]

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

makeName() { 
    echo -n "Enter Ext: " 
    read ext 

    __="$fileName.$1.$ext.log" 
} 


echo -n "Enter fileName:" 
read fileName 

makeName "type1" ; name1=${__} 
makeName "type2" ; name2=${__} 

echo $name1 
echo $name2 
$ ./sample.sh 
Enter fileName:filename 
Enter Ext: ext1 
Enter Ext: ext2 
filename.type1.ext1.log 
filename.type2.ext2.log 

फिर भी तरह बेहतर है, क्लीनर कोड के लिए और अपने समारोह के अंदर वैश्विक चर का उपयोग कर से बचने के लिए, आप दृष्टिकोण Returning Values from Bash Functions और में वर्णित इस्तेमाल कर सकते हैं पैरामीटर के रूप में वापसी वैरिएबल का नाम गुजरती हैं, और आदर्श रूप में भी पैरामीटर के रूप में fileName पारित:

makeName() { 
    local __type=$1 
    local __fileName=$2 
    local __resultvar=$3 
    local ext 
    local myresult 

    echo -n "Enter Ext: " 
    read ext 
    myresult="$__fileName.$__type.$ext.log" 

    eval $__resultvar="'$myresult'" 
} 

echo -n "Enter fileName:" 
read fileName 

makeName "type1" $fileName theResult ; name1=${theResult} 
makeName "type2" $fileName theResult ; name2=${theResult} 
echo $myresult 

echo $name1 
echo $name2 

साइड नोट: चर्चा के लिए Why should eval be avoided in Bash, and what should I use instead? देखें eval से बचा जाना चाहिए। बैश संस्करण 3.1 या उच्चतर का उपयोग करते समय, आप eval के बजाय printf उपयोग कर सकते हैं:

... 
printf -v "$__resultvar" '%s' "$myresult" 
... 

और अंत में, पार्टी के साथ 4.3 या उसके बाद, हम एक चर declare -n का उपयोग करने के nameref विशेषता असाइन कर सकते हैं ताकि चर को प्रभावी ढंग से एक और चर के लिए एक संदर्भ है:

... 
declare -n myresult=$3 

myresult="$__fileName.$__type.$ext.log" 
... 
+0

हाय एंड्रियास, मैं अपने प्रश्न को अद्यतन किया है। – Ashwin

+1

मेरा अद्यतन उत्तर देखें - अनिवार्य रूप से, आपने 'रिटर्न' का दुरुपयोग किया है, और आपको @ कंसोलबॉक्स द्वारा प्रस्तावित दृष्टिकोण का उपयोग करने की भी आवश्यकता है जब आपका फ़ंक्शन stdout (वापसी मूल्य के अलावा) आउटपुट प्रिंट करने का इरादा रखता है –

+0

धन्यवाद एंड्रियास। यह अभी ठीक काम करता है। :) – Ashwin

4

बेहतर तरीका एक सामान्य चर आप हमेशा इस्तेमाल कर सकते हैं लेने के लिए है।उदाहरण:

makeName() { 
    __="$fileName.$1.log" 
}  

echo -n "Enter fileName:" 
read fileName 

makeName "type1" 
name1=$__ 
makeName "type2" 
name2=$__ 

echo "$name1" 
echo "$name2" 

फ़ंक्शन से मूल्य प्राप्त करने के लिए केवल उपशीर्षक को सारांशित करना वास्तव में अक्षम और धीमा है।

+0

उप-शैल पर +1 अच्छा बिंदु - मैं शायद वैश्विक चरों पर उप-गोले को भी पसंद करूंगा ;-), लेकिन आपका दृष्टिकोण निश्चित रूप से तेज़ है (दो 'मेकनाम' कॉल लूपिंग 100 गुना कम से कम 100ms लेता है, जबकि उप शैल आधारित समाधान लगभग 2 सेकंड लेता है)। –

+0

बैश की गुप्त प्रकृति मुझे कभी आश्चर्यचकित नहीं करती :-) – raffian

0

बस echo साथ return बदल देते हैं:

makeName() 
{ 
    echo "Enter Ext: " >&2 
    read ext 
    echo "$fileName.$1.$ext.log" 
} 
+1

वह 'एंटर एक्सटी' के साथ खत्म हो जाएगा: परिणाम का हिस्सा होने के नाते ... –

+0

ओह। प्रॉम्प्ट को इसके बजाय प्रॉम्प्ट प्रदर्शित करने के लिए 'read 'के' bash' के कार्यान्वयन के लिए उपलब्ध '-p' विकल्प' के साथ या तो 'echo' एंटर करें:"> और 2' के साथ मानक त्रुटि पर मुद्रित किया जाना चाहिए ('read -p" एंटर करें: "ext')। – chepner

+0

... और, आपको अभी भी 'मेकनाम' को कॉल करते समय कमांड प्रतिस्थापन का उपयोग करने की आवश्यकता है (जो ओपी सही तरीके से नहीं करता है, और जो चर्चा हमारे पास @konsolebox ;-) के साथ हुई थी) –