স্ক্রিপ্টগুলিতে পরিবর্তনশীল অ্যাসাইনমেন্টের জন্য “$ {a: -b}” ব্যবহার করা হচ্ছে


426

আমি অন্যান্য স্ক্রিপ্টগুলি অন্য লোকেরা লিখেছেন (বিশেষত রেড হ্যাট), এবং তাদের প্রচুর ভেরিয়েবল নীচের স্বরলিপি ব্যবহার করে নির্ধারণ করা হয়েছে VARIABLE1="${VARIABLE1:-some_val}" বা কিছু অন্যান্য ভেরিয়েবল প্রসারিত করছে VARIABLE2="${VARIABLE2:-`echo $VARIABLE1`}"

কেবলমাত্র মানগুলি সরাসরি (উদাহরণস্বরূপ VARIABLE1=some_val) ঘোষণার পরিবর্তে এই স্বরলিপিটি ব্যবহার করার কী দরকার ?

এই চিহ্নিতকরণের কোনও সুবিধা বা সম্ভাব্য ত্রুটিগুলি প্রতিরোধ করা যেতে পারে?

না :-এই প্রেক্ষাপটে নির্দিষ্ট অর্থ আছে?


একবার দেখুন man bash; "প্যারামিটার সম্প্রসারণ" ব্লকটি অনুসন্ধান করুন (প্রায় ২৮%)। এই অ্যাসাইনমেন্টগুলি উদাহরণস্বরূপ ডিফল্ট ফাংশন: "ডিফল্ট মানটি তখনই ব্যবহার করুন যদি কোনওটি এখনও সেট না করা হয়।"
হউক লেগেছে 0

উত্তর:


695

এই কৌশলটি কোনও ভেরিয়েবলকে একটি মান নির্ধারণের অনুমতি দেয় যদি অন্য ভেরিয়েবল হয় হয় ফাঁকা হয় বা অপরিজ্ঞাত থাকে। দ্রষ্টব্য: এই "অন্যান্য পরিবর্তনশীল" একই বা অন্য পরিবর্তনশীল হতে পারে।

উদ্ধৃতাংশ

${parameter:-word}
    If parameter is unset or null, the expansion of word is substituted. 
    Otherwise, the value of parameter is substituted.

দ্রষ্টব্য: এই ফর্মটিও কাজ করে ${parameter-word},। আপনি যদি বাশের মধ্যে উপলব্ধ সমস্ত আকারের প্যারামিটার বিস্তারের সম্পূর্ণ তালিকা দেখতে চান তবে আমি আপনাকে পরামর্শ দিচ্ছি বাশ হ্যাকারের উইকি শিরোনাম: " প্যারামিটার সম্প্রসারণ " শিরোনামে এই বিষয়টি একবার দেখুন ।

উদাহরণ

ভেরিয়েবলের অস্তিত্ব নেই
$ echo "$VAR1"

$ VAR1="${VAR1:-default value}"
$ echo "$VAR1"
default value
পরিবর্তনশীল বিদ্যমান
$ VAR1="has value"
$ echo "$VAR1"
has value

$ VAR1="${VAR1:-default value}"
$ echo "$VAR1"
has value

অন্যান্য ভেরিয়েবলগুলি মূল্যায়ন করে, বা স্বরলিপিটির ডিফল্ট মান অংশের মধ্যে চালানো আদেশগুলি একই জিনিসটি করা যেতে পারে।

$ VAR2="has another value"
$ echo "$VAR2"
has another value
$ echo "$VAR1"

$

$ VAR1="${VAR1:-$VAR2}"
$ echo "$VAR1"
has another value

আরও উদাহরণ

এটি সামান্য যেখানে আপনি কিছুটা আলাদা স্বরলিপি ব্যবহার করতে পারেন VARX=${VARX-<def. value>}

$ echo "${VAR1-0}"
has another value
$ echo "${VAR2-0}"
has another value
$ echo "${VAR3-0}"
0

উপরেরটিতে $VAR1এবং $VAR2ইতিমধ্যে স্ট্রিংটির সাথে "অন্য মান রয়েছে" সংজ্ঞায়িত করা $VAR3হয়েছিল তবে এটি অপরিবর্তিত ছিল, সুতরাং এর পরিবর্তে ডিফল্ট মানটি ব্যবহৃত হত 0,।

আরেকটি উদাহরণ

$ VARX="${VAR3-0}"
$ echo "$VARX"
0

:=স্বরলিপি ব্যবহার করে পরীক্ষা করা এবং নির্ধারণ করা

অবশেষে আমি হ্যান্ডি অপারেটরের কথা উল্লেখ করব :=,। পরীক্ষার অধীনে চলকটি খালি বা অপরিজ্ঞাত থাকলে এটি একটি চেক করবে এবং একটি মান নির্ধারণ করবে।

উদাহরণ

লক্ষ্য $VAR1এখন সেট করা আছে। অপারেটর :=একক অপারেশনে পরীক্ষা এবং অ্যাসাইনমেন্টটি করেছিলেন।

$ unset VAR1
$ echo "$VAR1"

$ echo "${VAR1:=default}"
default
$ echo "$VAR1"
default

তবে মানটি যদি আগে সেট করা থাকে তবে তা একা থাকে।

$ VAR1="some value"
$ echo "${VAR1:=default}"
some value
$ echo "$VAR1"
some value

হ্যান্ডি ড্যান্ডি রেফারেন্স টেবিল

    টেবিলের এসএস

তথ্যসূত্র


8
মনে রাখবেন যে এগুলি সমস্তই বিস্তৃত নয় bash${var:-word}প্রশ্নঃ এক, কিন্তু ${var-word}উপরে। পসিক্স ডকুমেন্টেশনটিতে একটি দুর্দান্ত টেবিল রয়েছে, তবে এটি এই উত্তরটি অনুলিপি করার উপযুক্ত হতে পারে - পাবস.ওপেনগ্রুপ.আর
গ্রেম

5
@ গ্র্যামি, এটি নথিভুক্ত করা হয়েছে, কেবলমাত্র অনসেট করা প্যারামিটারের পরীক্ষার জন্য আপনার কেবলমাত্র কোলনের ফলাফলের
স্টাফেন চেজেলাস

7
echo "${FOO:=default}"আপনি যদি আসলে চান তবে ব্যবহার করা দুর্দান্ত echo। তবে আপনি যদি তা না করেন তবে :অন্তর্নির্মিতটি চেষ্টা করুন ... : ${FOO:=default} আপনার উপরের হিসাবে $FOOসেট করা আছে default(যেমন ইতিমধ্যে সেট না থাকলে)। তবে $FOOপ্রক্রিয়াটির কোনও প্রতিধ্বনি নেই ।
fbicknel

2
ঠিক আছে, একটি উত্তর খুঁজে পেয়েছি: stackoverflow.com/q/24405606/1172302${4:-$VAR}উইল ব্যবহার করে কাজ হবে।
নিকস আলেকজান্দ্রিস

1
আপনাকে 500 এনে দিতে এখানে একটি +1 করুন। অভিনন্দন! :)
এক্সট্রাস্পিলিটিটি

17

@ এসএলএম ইতিমধ্যে পসিক্স ডক্সকে অন্তর্ভুক্ত করেছে - যা খুব সহায়ক - তবে কীভাবে এই পরামিতিগুলি একে অপরকে প্রভাবিত করতে একত্রিত করা যায় সে সম্পর্কে তারা সত্যই প্রসারিত করে না। এই ফর্মটির এখানে এখনও কোনও উল্লেখ নেই:

${var?if unset parent shell dies and this message is output to stderr}

এটি আমার অন্য একটি উত্তরের একটি অংশ, এবং আমি মনে করি এটি কীভাবে এই কাজ করে তা খুব ভালভাবে প্রদর্শন করে:

    sh <<-\CMD
    _input_fn() { set -- "$@" #redundant
            echo ${*?WHERES MY DATA?}
            #echo is not necessary though
            shift #sure hope we have more than $1 parameter
            : ${*?WHERES MY DATA?} #: do nothing, gracefully
    }
    _input_fn heres some stuff
    _input_fn one #here
    # shell dies - third try doesnt run
    _input_fn you there?
    # END
    CMD
heres some stuff
one
sh: line :5 *: WHERES MY DATA?

একই থেকে অন্য একটি উদাহরণ :

    sh <<-\CMD
    N= #N is NULL
    _test=$N #_test is also NULL and
    v="something you would rather do without"    
    ( #this subshell dies
        echo "v is ${v+set}: and its value is ${v:+not NULL}"
        echo "So this ${_test:-"\$_test:="} will equal ${_test:="$v"}"
        ${_test:+${N:?so you test for it with a little nesting}}
        echo "sure wish we could do some other things"
    )
    ( #this subshell does some other things 
        unset v #to ensure it is definitely unset
        echo "But here v is ${v-unset}: ${v:+you certainly wont see this}"
        echo "So this ${_test:-"\$_test:="} will equal NULL ${_test:="$v"}"
        ${_test:+${N:?is never substituted}}
        echo "so now we can do some other things" 
    )
    #and even though we set _test and unset v in the subshell
    echo "_test is still ${_test:-"NULL"} and ${v:+"v is still $v"}"
    # END
    CMD
v is set: and its value is not NULL
So this $_test:= will equal something you would rather do without
sh: line 7: N: so you test for it with a little nesting
But here v is unset:
So this $_test:= will equal NULL
so now we can do some other things
_test is still NULL and v is still something you would rather do without

উপরের উদাহরণটি পসিক্স প্যারামিটার বিকল্পের সমস্ত 4 ফর্ম এবং তাদের বিভিন্ন :colon nullবা not nullপরীক্ষার সুবিধা গ্রহণ করে। উপরের লিঙ্কটিতে আরও তথ্য রয়েছে এবং এটি আবার এখানে রয়েছে

লোকেদের প্রায়শই বিবেচনা করা হয় না ${parameter:+expansion}তা হ'ল এখানে-নথিতে এটি কতটা কার্যকর হতে পারে। এখানে ভিন্ন উত্তর থেকে অন্য একটি অংশ দেওয়া হয়েছে :

শীর্ষ

এখানে আপনি কিছু ডিফল্ট সেট করবেন এবং ডেকে এগুলি মুদ্রণের জন্য প্রস্তুত হবেন ...

#!/bin/sh
    _top_of_script_pr() ( 
        IFS="$nl" ; set -f #only split at newlines and don't expand paths
        printf %s\\n ${strings}
    ) 3<<-TEMPLATES
        ${nl=
}
        ${PLACE:="your mother's house"}
        ${EVENT:="the unspeakable."}
        ${ACTION:="heroin"}
        ${RESULT:="succeed."}
        ${strings:="
            I went to ${PLACE} and saw ${EVENT}
            If you do ${ACTION} you will ${RESULT}
        "}
    #END
    TEMPLATES

MIDDLE

আপনি অন্য ফাংশনগুলির ফলাফলের উপর ভিত্তি করে আপনার মুদ্রণ ফাংশনটিতে কল করার জন্য এটি সংজ্ঞা দিয়েছেন ...

    EVENT="Disney on Ice."
    _more_important_function() { #...some logic...
        [ $((1+one)) -ne 2 ] && ACTION="remedial mathematics"
            _top_of_script_pr
    }
    _less_important_function() { #...more logic...
        one=2
        : "${ACTION:="calligraphy"}"
        _top_of_script_pr
    }

থেকে BOTTOM

আপনার এখন এটি সমস্ত সেটআপ হয়ে গেছে, সুতরাং আপনি যেখানে ফলাফলগুলি কার্যকর করবেন এবং টানবেন তা এখানে।

    _less_important_function
    : "${PLACE:="the cemetery"}" 
    _more_important_function
    : "${RESULT:="regret it."}" 
    _less_important_function    

ফলাফল

আমি কেন এক মুহুর্তের মধ্যে চলে যাব, তবে উপরোক্ত চালনা করলে নিম্নলিখিত ফলাফল পাওয়া যায়:

_less_important_function()'s প্রথম রান:

আমি তোমার মায়ের বাড়িতে গিয়ে দেখলাম ডিজনি অন আইস।

আপনি যদি ক্যালিগ্রাফি করেন তবে আপনি সফল হবেন।

তারপর _more_important_function():

আমি কবরস্থানে গিয়ে দেখি ডিজনি অন আইস।

যদি আপনি না নিরাময়কারী গণিত আপনি সফল হবে।

_less_important_function() আবার

আমি কবরস্থানে গিয়ে দেখি ডিজনি অন আইস।

প্রতিকারমূলক গণিতটি করলে আপনি আফসোস করবেন

কিভাবে এটা কাজ করে:

এখানে মূল বৈশিষ্ট্যটি হ'ল ধারণাটি হ'ল conditional ${parameter} expansion.আপনি যদি কোনও ফর্মটি সেট না করে বা নাল হয়ে থাকে তবেই কোনও মানকে একটি পরিবর্তনশীল সেট করতে পারেন:

${var_name: =desired_value}

পরিবর্তে আপনি যদি কেবল একটি আনসেট ভেরিয়েবল সেট করতে চান তবে আপনি বাদ পড়বেন :colonএবং নাল মানগুলি যেমন থাকবে তেমন থাকবে।

স্কোপে:

আপনি লক্ষ্য করতে পারেন যে উপরের উদাহরণে $PLACEএবং ইতিমধ্যে বলা হয়ে গেলেও $RESULTসেট হয়ে গেলে পরিবর্তিত হয়ে উঠবেন, সম্ভবত এটি চালানোর সময় সেগুলি সেট করুন। এটি কাজ করার কারণটি হ'ল এটি একটি ফাংশন - আমি অন্যের জন্য ব্যবহৃত না হয়ে এটি এটিকে ঘিরে রেখেছি । যেহেতু এটিকে একটি সাবশেলে ডাকা হয়, তাই এটি নির্ধারিত প্রতিটি পরিবর্তনশীল হয় এবং এটি তার পিতামাতার শেলের কাছে ফিরে আসে সেই মানগুলি অদৃশ্য হয়ে যায়।parameter expansion_top_of_script_pr()_top_of_script_pr()( subshelled )parens{ curly braces }locally scoped

তবে _more_important_function()সেটগুলি যখন $ACTIONএটি হয় globally scopedতখন এটি _less_important_function()'sদ্বিতীয় মূল্যায়নকে প্রভাবিত করে $ACTIONকারণ কেবলমাত্র মাধ্যমে _less_important_function()সেট করে$ACTION${parameter:=expansion}.


1
শর্টহ্যান্ড ডিফল্ট মান বোর্ন শেল-এ কাজ করে দেখলে ভালো
শ্রীধর সারনোবাত

8

ব্যক্তিগত অভিজ্ঞতা.

আমি কখনও কখনও আমার স্ক্রিপ্টগুলিতে এই স্ক্রিপ্টগুলিতে মানগুলির অতিরিক্ত-রাইডিং করতে ব্যবহার করি, যেমন আমার যদি থাকে:

$ cat script.sh
SOMETHING="${SOMETHING:-something}"; echo "$SOMETHING"; 

আমি রান করতে পারি:

$ env SOMETHING="something other than the default value" ./script.sh` 

এর মূল ডিফল্ট মান পরিবর্তন না করেই SOMETHING

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.