एक बैश फ़ंक्शन जो अन्य भाषाओं की तरह तर्क लेता है?


17

मेरे पास $PATHइस तरह सेट करने के लिए एक बश फ़ंक्शन है -

assign-path()
{
    str=$1
    # if the $PATH is empty, assign it directly.
    if [ -z $PATH ]; then
        PATH=$str;
    # if the $PATH does not contain the substring, append it with ':'.
    elif [[ $PATH != *$str* ]]; then
        PATH=$PATH:$str;
    fi
}

लेकिन समस्या यह है, मुझे अलग-अलग चर के लिए अलग-अलग फ़ंक्शन लिखना होगा (उदाहरण के लिए, $CLASSPATHजैसे के लिए एक और फ़ंक्शनassign-classpath() )। मुझे बैश फ़ंक्शन में तर्क पास करने का कोई तरीका नहीं मिला, ताकि मैं इसे संदर्भ द्वारा एक्सेस कर सकूं।

यह बेहतर होगा यदि मेरे पास कुछ है -

assign( bigstr, substr )
{
    if [ -z bigstr ]; then
        bigstr=substr;
    elif [[ bigstr != *str* ]]; then
        bigstr=bigstr:substr;
    fi
}

किसी भी विचार, कैसे ऊपर की तरह कुछ को प्राप्त करने के लिए बैश में?


क्या "अन्य भाषाओं"?
चोराबा

ठीक है, मैंने यह
कहने

1
assign-path /abcसंलग्न नहीं होंगे /abcपथ के लिए $ पथ पहले से ही शामिल है /abc/def, /abcd, /def/abcआदि विशेष रूप से आप को नहीं जोड़ सकते /binपथ पहले से ही शामिल है /usr/bin
चमत्कार 173

@ miracle173 - यह सच है, तुम क्या करने की जरूरत है विभाजित है $PATHऔर इस तरह अपने तर्क के खिलाफ निगेट परीक्षण: add=/bin dir=/usr/bin ; [ -z "${dir%"$add"}" ] || dir="${dir}:${add}"मेरे जवाब में मैं इसे इस तरह से करता हूं जितने भी तर्कों के साथ आप केवल उपयोग करना पसंद करते हैं IFS=:
मोकेसर

बृहदान्त्र-पृथक सूचियों में मूल्यों को जोड़ने के विशिष्ट (उदाहरण) मुद्दे से संबंधित: मैं सफाई से कैसे जोड़ सकता हूं  $PATH?  और निर्देशिका जोड़ें $PATHअगर यह पहले से ही वहाँ नहीं है ( सुपर उपयोगकर्ता पर )।
स्कॉट

जवाबों:


17

में bashआप उपयोग कर सकते हैं ${!varname}चर एक और की सामग्री द्वारा संदर्भित विस्तार करने के लिए। उदाहरण के लिए:

$ var=hello
$ foo () { echo "${!1}"; }
$ foo var
hello

मैन पेज से:

${!prefix*}
${!prefix@}
       Names matching prefix.  Expands to the names of variables whose names
       begin with prefix, separated by the first character of the IFS special
       variable.  When @ is used  and the expansion appears within double quotes,
       each variable name expands to a separate word.

इसके अलावा, सामग्री द्वारा संदर्भित एक चर सेट करने के लिए (खतरों के बिना eval), आप उपयोग कर सकते हैं declare। उदाहरण के लिए:

$ var=target
$ declare "$var=hello"
$ echo "$target"
hello

इस प्रकार, आप अपने फ़ंक्शन को इस तरह लिख सकते हैं (ध्यान रखें क्योंकि यदि आप declareकिसी फ़ंक्शन में उपयोग करते हैं, तो आपको देना होगा -gया चर स्थानीय होगा):

shopt -s extglob

assign()
{
  target=$1
  bigstr=${!1}
  substr=$2

  if [ -z "$bigstr" ]; then
    declare -g -- "$target=$substr"
  elif [[ $bigstr != @(|*:)$substr@(|:*) ]]; then
    declare -g -- "$target=$bigstr:$substr"
  fi
}

और इसका उपयोग करें:

assign PATH /path/to/binaries

ध्यान दें कि मैंने एक बग को भी ठीक किया है जहां अगर substrपहले से ही बृहदान्त्र के अलग सदस्यों में से एक का विकल्प है bigstr, लेकिन इसका अपना सदस्य नहीं है, तो इसे जोड़ा नहीं जाएगा। उदाहरण के लिए, यह पहले से ही /binएक PATHचर में जोड़ने की अनुमति देगा /usr/bin। यह extglobस्ट्रिंग या एक कोलन की शुरुआत / अंत से मेल खाने के लिए सेट का उपयोग करता है और फिर कुछ भी। इसके बिना extglob, विकल्प होगा:

[[ $bigstr != $substr && $bigstr != *:$substr &&
   $bigstr != $substr:* && $bigstr != *:$substr:* ]]

-gमें declareपार्टी के पुराने संस्करण में उपलब्ध नहीं है, वहाँ किसी भी तरह से इतना है कि मैं इस पिछड़े संगत बनाने के कर सकते हैं?
रामगुरुर

2
@ramgorur, आप exportइसे अपने वातावरण में डालने के लिए उपयोग कर सकते हैं (कुछ महत्वपूर्ण ओवरराइटिंग के जोखिम पर) या eval(सुरक्षा सहित विभिन्न मुद्दों पर अगर आप सावधान नहीं हैं)। यदि का उपयोग कर evalआप चाहिए ठीक हो आप की तरह यह कर यदि eval "$target=\$substr"। यदि आप \ हालांकि भूल जाते हैं , तो यह संभावित रूप से एक कमांड निष्पादित करेगा यदि सामग्री में जगह हैsubstr
ग्रीम

9

बाश 4.3 में नया, & : का -nविकल्प हैdeclarelocal

func() {
    local -n ref="$1"
    ref="hello, world"
}

var='goodbye world'
func var
echo "$var"

वह प्रिंट करता है hello, world


बैश में namerefs के साथ एकमात्र समस्या यह है कि आपके पास nameref के समान नाम के फ़ंक्शन (फ़ंक्शन के बाहर) के एक वेरिएबल को संदर्भित करने के लिए एक nameref (उदाहरण के लिए फ़ंक्शन में) नहीं हो सकता है। यह हालांकि 4.5 रिलीज के लिए तय किया जा सकता है।
कुसलानंद

2

आप evalएक पैरामीटर सेट करने के लिए उपयोग कर सकते हैं । इस कमांड का विवरण यहां पाया जा सकता है । के निम्न उपयोगeval गलत है:

गलत(){
  eval $ 1 = $ 2
}

अतिरिक्त मूल्यांकन के संबंध में eval आपको उपयोग करना चाहिए

असाइन () {
  eval $ 1 = '$ 2'
}

इन कार्यों का उपयोग करने के परिणामों की जाँच करें:

$ X1 = '$ X2'
$ X2 = '$ X3'
$ X3 = 'xxx'
$ 
$ प्रतिध्वनि: $ X1:
: $ X2:
$ गूंज: $ X2:
: $ X3:
$ गूंज: $ X3:
: Xxx:
$ 
$ गलत Y $ X1
$ गूंज: $ Y:
: $ X3:
$ 
$ असाइन करें Y $ X1
$ गूंज: $ Y:
: $ X2:
$ 
$ असाइन करें Y "हैलो वर्ल्ड"
$ गूंज: $ Y:
: हैलो दुनिया:
$ # निम्नलिखित अप्रत्याशित हो सकता है
$ असाइन Z $ Y
$ गूंज ": $ Z:"
: Hallo:
$ # तो आपको दूसरा तर्क उद्धृत करना होगा यदि इसका एक चर
$ असाइन करें Z "$ Y"
$ गूंज ": $ Z:"
: हैलो दुनिया:

लेकिन आप अपने लक्ष्य को बिना उपयोग किए हासिल कर सकते हैं eval। मैं इस तरह से पसंद करता हूं जो अधिक सरल है।

निम्नलिखित कार्य सही तरीके से प्रतिस्थापन बनाता है (मुझे आशा है)

बढ़ाने () {
  स्थानीय मुद्रा = $ 1
  लोकल ऑगमेंट = $ 2
  स्थानीय नई
  अगर [[-z $ CURRENT]]; फिर
    नई = $ बढ़ाने
  एलिफ [[! (($ CURRENT = $ AUGMENT) || ($ CURRENT = $ AUGMENT: *) \ _ ||
    ($ CURRENT = *: $ AUGMENT) || ($ CURRENT = *: $ AUGMENT: *)]]]; फिर
    नई = $ वर्तमान: $ बढ़ाने
  अन्य
    नई $ वर्तमान =
    फाई
  इको "$ नया"
}

निम्नलिखित आउटपुट की जाँच करें

वृद्धि / usr / बिन / बिन
/ Usr / bin: / bin

वृद्धि / usr / बिन: / बिन / बिन
/ Usr / bin: / bin

वृद्धि / usr / बिन: / बिन: / usr / स्थानीय / बिन / बिन
/ Usr / bin: / बिन: / usr / स्थानीय / बिन

वृद्धि / बिन: / usr / बिन / बिन
/ Bin: / usr / bin

वृद्धि / बिन / बिन
/ bin


वृद्धि / usr / बिन: / बिन
/ Usr / bin :: / bin

वृद्धि / usr / बिन: / बिन: / बिन
/ Usr / bin: / बिन:

वृद्धि / usr / बिन: / बिन: / usr / स्थानीय / बिन: / बिन
/ Usr / bin: / बिन: / usr / स्थानीय / बिन:

वृद्धि / बिन: / usr / बिन: / बिन
/ Bin: / usr / bin:

वृद्धि / बिन: / बिन
/ Bin:


वृद्धि: / बिन
:: / bin


वृद्धि "/ usr lib" "/ usr बिन"
/ usr lib: / usr बिन

वृद्धि "/ usr lib: / usr बिन" "/ usr बिन"
/ usr lib: / usr बिन

अब आप augmentचर को सेट करने के लिए फ़ंक्शन का उपयोग निम्न तरीके से कर सकते हैं :

पथ = `वृद्धि पथ / बिन`
CLASSPATH = `वृद्धि CLASSPATH / bin`
LD_LIBRARY_PATH = `वृद्धि LD_LIBRARY_PATH / usr / lib`

यहां तक ​​कि आपका निष्कासन कथन भी गलत है। यह, उदाहरण के लिए: v='echo "OHNO!" ; var' ; l=val ; eval $v='$l' - "ओएचएनओ" को प्रतिध्वनित करने से पहले! आप "$ {v ## * [?; के साथ मूल्यांकन नहीं किया जाएगा =
mikeserv

@ mikeserv आपकी टिप्पणी के लिए धन्यवाद, लेकिन मुझे लगता है कि यह एक वैध उदाहरण नहीं है। असाइन स्क्रिप्ट का पहला तर्क एक चर नाम या एक चर होना चाहिए जिसमें एक चर नाम होता है जो कि =असाइनमेंट स्टेटमेंट के बाईं ओर उपयोग किया जाता है । आप तर्क दे सकते हैं कि मेरी राशि इसके तर्क की जांच नहीं करती है। यह सच है। मैं यह भी जाँच नहीं करता कि क्या कोई तर्क है या यदि तर्कों की संख्या वैध है। लेकिन यह इरादे से था। ओपी चाहे तो ऐसे चेक जोड़ सकता है।
चमत्कार 173

@mikeserv: मुझे लगता है कि पहला तर्क चुपचाप वैध चर नाम में बदलने का आपका प्रस्ताव अच्छा विचार नहीं है: 1) कुछ चर सेट / ओवरराइट किया गया है जो उपयोगकर्ता द्वारा अभिप्रेत नहीं था। 2) त्रुटि फ़ंक्शन के उपयोगकर्ता से छिपी हुई है। यह कभी अच्छा विचार नहीं है। अगर ऐसा होता है तो बस एक त्रुटि उठानी चाहिए।
चमत्कार 173

@mikeserv: यह दिलचस्प है जब कोई आपके चर v(बेहतर मूल्य) का उपयोग करना चाहता है , जो असाइन किए गए फ़ंक्शन के दूसरे तर्क के रूप में होता है। तो इसका मूल्य एक असाइनमेंट के दाहिने हाथ की तरफ होना चाहिए। फ़ंक्शन के तर्क को उद्धृत करना आवश्यक है assign। मैंने अपनी पोस्टिंग में इस सूक्ष्मता को जोड़ा।
चमत्कार 173

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

2

कुछ ट्रिक्स के साथ आप वास्तव में नामांकित मापदंडों को फ़ंक्शन के साथ पारित कर सकते हैं, साथ में सरणियाँ (बैश 3 और 4 में परीक्षण)।

मैंने जो विधि विकसित की है वह आपको इस तरह से कार्य करने के लिए दिए गए मापदंडों का उपयोग करने की अनुमति देता है:

testPassingParams() {

    @var hello
    l=4 @array anArrayWithFourElements
    l=2 @array anotherArrayWithTwo
    @var anotherSingle
    @reference table   # references only work in bash >=4.3
    @params anArrayOfVariedSize

    test "$hello" = "$1" && echo correct
    #
    test "${anArrayWithFourElements[0]}" = "$2" && echo correct
    test "${anArrayWithFourElements[1]}" = "$3" && echo correct
    test "${anArrayWithFourElements[2]}" = "$4" && echo correct
    # etc...
    #
    test "${anotherArrayWithTwo[0]}" = "$6" && echo correct
    test "${anotherArrayWithTwo[1]}" = "$7" && echo correct
    #
    test "$anotherSingle" = "$8" && echo correct
    #
    test "${table[test]}" = "works"
    table[inside]="adding a new value"
    #
    # I'm using * just in this example:
    test "${anArrayOfVariedSize[*]}" = "${*:10}" && echo correct
}

fourElements=( a1 a2 "a3 with spaces" a4 )
twoElements=( b1 b2 )
declare -A assocArray
assocArray[test]="works"

testPassingParams "first" "${fourElements[@]}" "${twoElements[@]}" "single with spaces" assocArray "and more... " "even more..."

test "${assocArray[inside]}" = "adding a new value"

दूसरे शब्दों में, न केवल आप अपने मापदंडों को उनके नाम से बुला सकते हैं (जो कि अधिक पठनीय कोर के लिए बनाता है), आप वास्तव में सरणियों को पारित कर सकते हैं (और चर के संदर्भ में - यह सुविधा केवल बाश 4.3 में हालांकि काम करती है)! इसके अलावा, मैप किए गए चर सभी स्थानीय दायरे में हैं, बस $ 1 (और अन्य) के रूप में।

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

Function.AssignParamLocally() {
    local commandWithArgs=( $1 )
    local command="${commandWithArgs[0]}"

    shift

    if [[ "$command" == "trap" || "$command" == "l="* || "$command" == "_type="* ]]
    then
        paramNo+=-1
        return 0
    fi

    if [[ "$command" != "local" ]]
    then
        assignNormalCodeStarted=true
    fi

    local varDeclaration="${commandWithArgs[1]}"
    if [[ $varDeclaration == '-n' ]]
    then
        varDeclaration="${commandWithArgs[2]}"
    fi
    local varName="${varDeclaration%%=*}"

    # var value is only important if making an object later on from it
    local varValue="${varDeclaration#*=}"

    if [[ ! -z $assignVarType ]]
    then
        local previousParamNo=$(expr $paramNo - 1)

        if [[ "$assignVarType" == "array" ]]
        then
            # passing array:
            execute="$assignVarName=( \"\${@:$previousParamNo:$assignArrLength}\" )"
            eval "$execute"
            paramNo+=$(expr $assignArrLength - 1)

            unset assignArrLength
        elif [[ "$assignVarType" == "params" ]]
        then
            execute="$assignVarName=( \"\${@:$previousParamNo}\" )"
            eval "$execute"
        elif [[ "$assignVarType" == "reference" ]]
        then
            execute="$assignVarName=\"\$$previousParamNo\""
            eval "$execute"
        elif [[ ! -z "${!previousParamNo}" ]]
        then
            execute="$assignVarName=\"\$$previousParamNo\""
            eval "$execute"
        fi
    fi

    assignVarType="$__capture_type"
    assignVarName="$varName"
    assignArrLength="$__capture_arrLength"
}

Function.CaptureParams() {
    __capture_type="$_type"
    __capture_arrLength="$l"
}

alias @trapAssign='Function.CaptureParams; trap "declare -i \"paramNo+=1\"; Function.AssignParamLocally \"\$BASH_COMMAND\" \"\$@\"; [[ \$assignNormalCodeStarted = true ]] && trap - DEBUG && unset assignVarType && unset assignVarName && unset assignNormalCodeStarted && unset paramNo" DEBUG; '
alias @param='@trapAssign local'
alias @reference='_type=reference @trapAssign local -n'
alias @var='_type=var @param'
alias @params='_type=params @param'
alias @array='_type=array @param'

1
assign () 
{ 
    if [ -z ${!1} ]; then
        eval $1=$2
    else
        if [[ ${!1} != *$2* ]]; then
            eval $1=${!1}:$2
        fi
    fi
}

$ echo =$x=
==
$ assign x y
$ echo =$x=
=y=
$ assign x y
$ echo =$x=
=y=
$ assign x z
$ echo =$x=
=y:z=

क्या यह फिट है?


नमस्ते, मैं इसे तुम्हारी तरह करने की कोशिश की, लेकिन काम नहीं कर रहा है, एक नौसिखिया होने के लिए खेद है। क्या आप मुझे बता सकते हैं कि इस स्क्रिप्ट में क्या गलत है ?
रामगुरुर

1
आपका उपयोग evalमनमाना कमांड निष्पादन के लिए अतिसंवेदनशील है।
क्रिस डाउन

आपके पास ज़ी evalलाइनों को सुरक्षित बनाने के लिए एक विचार है ? आम तौर पर, जब मुझे लगता है कि मुझे eval की आवश्यकता है, तो मैं तय करता हूं कि इसके बजाय एक अलग भाषा में * sh और स्विच का उपयोग न करें। दूसरी ओर, कुछ PATH जैसे चरों के लिए प्रविष्टियों को जोड़ने के लिए इस का उपयोग करते हुए, यह स्ट्रिंग स्थिरांक के साथ चलेगा और उपयोगकर्ता इनपुट नहीं ...

1
आप evalसुरक्षित रूप से कर सकते हैं - लेकिन यह बहुत विचार करता है। यदि आप केवल एक पैरामीटर को संदर्भित करने की कोशिश कर रहे हैं, तो आप कुछ इस तरह करना चाहेंगे: इस eval "$1=\"\$2\""तरह से eval'sपहली बार में यह केवल $ 1 का मूल्यांकन करता है और दूसरे पर इसका मूल्य = "$ 2" होता है। लेकिन आपको कुछ और करने की ज़रूरत है - यह यहाँ अनावश्यक है।
मोकेसर

दरअसल, मेरी उपरोक्त टिप्पणी भी गलत है। आप ऐसा नहीं करेंगे "${1##*[;"$IFS"]}=\"\$2\""- और यहां तक ​​कि बिना वारंटी के भी आता है। या eval "$(set -- $1 ; shift $(($#-1)) ; echo $1)=\"\$2\""। यह आसान नहीं है।
mikeserv

1

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

आप शायद एक अलग शेल स्क्रिप्ट (जैसे pythonया कुछ) को पूरी तरह से देखने के लिए बेहतर हैं यदि यह संभव है। यदि आप किसी भाषा की सीमाओं के विरुद्ध चल रहे हैं, तो आपको एक नई भाषा का उपयोग शुरू करना होगा।


शायद जल्दी में bashयह सच था। लेकिन अब विशिष्ट प्रावधान किए गए हैं। पूर्ण संदर्भ चर अब उपलब्ध हैं bash 4.3- derobert का उत्तर देखें ।
ग्रीम

और यदि आप यहाँ देखते हैं, तो आप देखेंगे कि आप इस तरह का काम वास्तव में आसानी से कर सकते हैं, बस POSIX पोर्टेबल कोड के साथ: unix.stackexchange.com/a/120531/52934
mikeserv

1

मानक shसिंटैक्स के साथ (में काम करेगा bash, और न केवल में bash), आप कर सकते हैं:

assign() {
  eval '
    case :${'"$1"'}: in
      (::) '"$1"'=$2;;   # was empty, copy
      (*:"$2":*) ;;      # already there, do nothing
      (*) '"$1"'=$1:$2;; # otherwise, append with a :
    esac'
}

का उपयोग कर समाधान के लिए की तरह bashहै declare, यह सुरक्षित रूप में लंबे समय के रूप में $1एक वैध चर नाम शामिल हैं।


0

NAMED ARGS पर:

यह बहुत ही सरलता से किया जाता है और bashइसकी बिल्कुल भी आवश्यकता नहीं होती है - यह पैरामीटर विस्तार के माध्यम से असाइनमेंट का मूल पोसिक्स निर्दिष्ट व्यवहार है:

: ${PATH:=this is only assigned to \$PATH if \$PATH is null or unset}

@Graeme के समान शिरा में डेमो करने के लिए, लेकिन पोर्टेबल तरीके से:

_fn() { echo "$1 ${2:-"$1"} $str" ; }

% str= ; _fn "${str:=hello}"
> hello hello hello

और वहां मैं केवल str=यह सुनिश्चित करने के लिए करता हूं कि इसमें एक शून्य मान है, क्योंकि पैरामीटर विस्तार में अंतर्निहित पर्यावरण को फिर से सेट करने पर शेल पर्यावरण को फिर से स्थापित करने के लिए अंतर्निहित सुरक्षा है।

समाधान:

आपकी विशिष्ट समस्या के लिए, मुझे विश्वास नहीं है कि नामित तर्क आवश्यक हैं, हालांकि वे निश्चित रूप से संभव हैं। $IFSइसके बजाय उपयोग करें :

assign() { oFS=$IFS ; IFS=: ; add=$* 
    set -- $PATH ; for p in $add ; do { 
        for d ; do [ -z "${d%"$p"}" ] && break 
        done ; } || set -- $* $p ; done
    PATH= ; echo "${PATH:="$*"}" ; IFS=$oFS
}

जब मैं इसे चलाता हूं तो मुझे यहां मिलता है:

% PATH=/usr/bin:/usr/yes/bin
% assign \
    /usr/bin \
    /usr/yes/bin \
    /usr/nope/bin \
    /usr/bin \
    /nope/usr/bin \
    /usr/nope/bin

> /usr/bin:/usr/yes/bin:/usr/nope/bin:/nope/usr/bin

% echo "$PATH"
> /usr/bin:/usr/yes/bin:/usr/nope/bin:/nope/usr/bin

% dir="/some crazy/dir"
% p=`assign /usr/bin /usr/bin/new "$dir"`
% echo "$p" ; echo "$PATH"
> /usr/bin:/usr/yes/bin:/usr/nope/bin:/nope/usr/bin:/some crazy/dir:/usr/bin/new
> /usr/bin:/usr/yes/bin:/usr/nope/bin:/nope/usr/bin:/some crazy/dir:/usr/bin/new

ध्यान दें कि इसमें केवल वही तर्क जोड़े गए जो पहले से नहीं थे $PATHया जो पहले आए थे? या यहां तक ​​कि यह एक से अधिक तर्क ले लिया? $IFSकाम है।


नमस्ते, मैं पालन करने में विफल रहा, तो क्या आप कृपया इसे थोड़ा और विस्तृत कर सकते हैं? धन्यवाद।
रामगुरुर

मैं पहले से ही ऐसा कर रहा हूँ ... बस कुछ और पल कृपया ...
mikeserv

@ramgorur कोई बेहतर? क्षमा करें, लेकिन वास्तविक जीवन में घुसपैठ हुई और मुझे लिखने-खत्म करने की उम्मीद से थोड़ा अधिक समय लगा।
mikeserv

यहाँ भी, वास्तविक जीवन के आगे घुटने टेक दिए। इस चीज को कोड करने के लिए बहुत सारे अलग-अलग तरीके पसंद करते हैं, मुझे सबसे अच्छे से निपटाने के लिए कुछ समय दें।
रामगुरुर

@ramgorur - बेशक, मैं यह सुनिश्चित करना चाहता था कि मैंने आपको फांसी नहीं दी। इसके बारे में - आप जो चाहें चुन लेते हैं, यार। मैं कहूंगा कि अन्य प्रस्तावों में से कोई भी मैं संक्षिप्त, पोर्टेबल, या मजबूत समाधान के रूप assignमें यहां देख सकता हूं । यदि आपके सवाल हैं कि यह कैसे काम करता है, तो मुझे उत्तर देने में खुशी होगी। और वैसे, यदि आप वास्तव में नामांकित तर्क चाहते हैं, तो आप मेरे इस दूसरे उत्तर को देख सकते हैं, जिसमें मैं दिखाता हूं कि किसी अन्य फ़ंक्शन के तर्कों के लिए एक फ़ंक्शन को कैसे घोषित किया जाए: unix.stackexchange.com/a/120531/52934
mikeserv

-2

मुझे रूबी, अजगर आदि कुछ भी नहीं मिल रहा है, लेकिन यह मेरे करीब लगता है

foo() {
  BAR="$1"; BAZ="$2"; QUUX="$3"; CORGE="$4"
  ...
}

मेरे विचार में पठनीयता बेहतर है, आपके पैरामीटर नामों की घोषणा के लिए 4 लाइनें अत्यधिक हैं। आधुनिक भाषाओं के भी करीब लगती है।


(1) प्रश्न शेल फंक्शंस के बारे में है। आपका जवाब एक कंकाल खोल समारोह प्रस्तुत करता है। इसके अलावा, आपके जवाब का सवाल से कोई लेना-देना नहीं है। (२) आपको लगता है कि यह अलग-अलग रेखाओं को ले जाने और पठनीयता बढ़ाने के लिए पठनीयता बढ़ाता है, जिससे अर्धविराम अलग-अलग होते हैं? मुझे विश्वास है कि आप इसे पीछे की ओर ले गए हैं; कि आपकी एक-पंक्ति शैली  बहु-पंक्ति शैली से कम पठनीय है।
स्कॉट

यदि अनावश्यक भागों को कम करना बिंदु है, तो उद्धरण और अर्धविराम क्यों? a=$1 b=$2 ...साथ ही काम करता है।
ilkachachu
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.