$ VAR বনাম $ {VAR} এবং উদ্ধৃত করা বা উদ্ধৃতি না দেওয়া


139

আমি লিখতে পারি

VAR=$VAR1
VAR=${VAR1}
VAR="$VAR1"
VAR="${VAR1}"

আমার কাছে শেষ ফলাফলটি একই রকম মনে হয়। কেন আমি একটি বা অন্য লিখতে হবে? এর মধ্যে কি কোনও পোর্টেবল / পসিক্স নয়?

উত্তর:


99

VAR=$VAR1এর সরলিকৃত সংস্করণ VAR=${VAR1}। দ্বিতীয়টি এমন কিছু কাজ করতে পারে যা প্রথম পারে না, উদাহরণস্বরূপ একটি অ্যারে সূচক (পোর্টেবল নয়) উল্লেখ করে বা একটি স্ট্রিং (পসিক্স-পোর্টেবল) অপসারণ করতে পারে। পসিক্স অনুচ্ছেদে প্রাথমিক ও পরামিতি বিস্তারের জন্য বাশ গাইডের আরও চলক বিভাগটি দেখুন ।

কোনও ভেরিয়েবলের চারপাশে উদ্ধৃতি ব্যবহার করা rm -- "$VAR1"বা rm -- "${VAR}"এটি একটি ভাল ধারণা। এটি ভেরিয়েবলের বিষয়বস্তুগুলিকে একটি পারমাণবিক ইউনিট করে তোলে। যদি ভেরিয়েবল $IFSমানটিতে ফাঁকা (ভাল, বিশেষ ভেরিয়েবলের অক্ষর , ডিফল্টরূপে ফাঁকা) বা গ্লোবিং অক্ষর থাকে এবং আপনি এটি উদ্ধৃত না করেন, তবে প্রতিটি শব্দটি ফাইল নাম উত্পাদন (গ্লোব্বিং) এর জন্য বিবেচনা করা হয় যার বিস্তৃতি আপনাকে যা কিছু যুক্তি দেয় করছি।

$ find .
.
./*r*
./-rf
./another
./filename
./spaced filename
./another spaced filename
./another spaced filename/x
$ var='spaced filename'
# usually, 'spaced filename' would come from the output of some command and you weren't expecting it
$ rm $var
rm: cannot remove 'spaced': No such file or directory
# oops! I just ran 'rm spaced filename'
$ var='*r*'
$ rm $var
# expands to: 'rm' '-rf' '*r*' 'another spaced filename'

$ find .
.
./another
./spaced filename
./another spaced filename
$ var='another spaced filename'
$ rm -- "$var"
$ find .
.
./another
./spaced filename

বহনযোগ্যতার উপর: পসিআইএক্স .১-২০০৮ বিভাগ ২. 2..২ অনুসারে , কোঁকড়া ধনুর্বন্ধনী .চ্ছিক


@ শন আমার প্রশ্ন আপডেট করেছেন কারণ আমি বহনযোগ্যতা সম্পর্কেও আগ্রহী
xenoterracide

@ শান: আমি সন্দেহ করি যে আপনার উদাহরণটি কার্যকর is আপনার কাছে এমন কোনও শেলের কোনও বাস্তব উদাহরণ আছে যেখানে var1=$varসম্প্রসারণ ত্রুটি দেয়?
অ্যালেক্স

@ অ্যালেক্স: ধন্যবাদ আমি ভেবেছিলাম আমি কমান্ড লাইনে এটি পরীক্ষা করেছি, তবে আমি এটি ভুল করেছি। উদাহরণ বদলেছি।
শন জে গফ

আপডেট হওয়া উদাহরণের সাথে এটি মনে রাখা ভাল যে আপনার সাধারণত উদ্ধৃত সংস্করণটি পাওয়া উচিত, কারণ উদাহরণটি বরং কোণার ক্ষেত্রে।
অ্যালেক্স

9
@ শ্যাওন: কোন অ্যাসাইনমেন্টে উদ্ধৃতিগুলি প্রয়োজনীয় নয় । এগুলি সহ অন্যান্য বেশিরভাগ ব্যবহারে এটি প্রয়োজনীয় export VAR=$VAR1। ধনুর্বন্ধনী হিসাবে, তারা alচ্ছিক (আপনার উদ্ধৃত অংশের চতুর্থ অনুচ্ছেদটি পরীক্ষা করুন; এটি সমস্ত প্রাক-পসিক্স এবং পসিক্স শেলের ক্ষেত্রে রয়েছে)।
গিলস

60

${VAR}এবং $VARঠিক সমতুল্য। একটি সরল ভেরিয়েবল প্রসারণের জন্য, কেবলমাত্র কারণটি ${VAR}যখন পার্সিং করা হয় তখন ভেরিয়েবল নামে অনেকগুলি অক্ষর দখল করতে পারে ${VAR1}_$VAR2( যেমন ধনুর্বন্ধনী ছাড়া সমান হবে ${VAR1_}$VAR2) use বেশিরভাগ সুসজ্জিত বিস্তারের ( ${VAR:=default},, ${VAR#prefix}…) জন্য ধনুর্বন্ধনী প্রয়োজন।

একটি পরিবর্তনশীল কার্যক্রমে, ক্ষেত্রের বিভাজন (যেমন মানের সাদা অংশে বিভক্ত হওয়া) এবং পথের নাম সম্প্রসারণ (অর্থাত্ গ্লোব্বিং) বন্ধ করা হয়, VAR=$VAR1ঠিক যেমনটি সমস্ত পসিক্স VAR="$VAR1"শেল এবং সমস্ত প্রাক পসিক্স শ এর মধ্যে শুনেছি to । (পজিক্স রেফ: সাধারণ আদেশগুলি )। একই কারণে, VAR=*নির্ভরযোগ্যভাবে VARআক্ষরিক স্ট্রিংয়ের জন্য সেট করে *; অবশ্যই VAR=a bসেট করে VARকরতে aযেহেতু bপ্রথম স্থানে একটি পৃথক শব্দ। সাধারণভাবে বলতে গেলে, ডবল কোট যেখানে শেল সিনট্যাক্স উদাহরণস্বরূপ, একটি কথাও আশা অপ্রয়োজনীয় হয় মধ্যেcase … in (কিন্তু প্যাটার্ন নেই), কিন্তু এমনকি সেখানে আপনি সতর্ক হতে প্রয়োজন: উদাহরণস্বরূপ POSIX নির্দিষ্ট করেপুনঃনির্দেশ লক্ষ্যগুলি ( >$filename) স্ক্রিপ্টগুলিতে উদ্ধৃতি প্রয়োজন হয় না, তবে বাশ সহ কয়েকটি শেলের জন্য এমনকি স্ক্রিপ্টগুলিতেও ডাবল উদ্ধৃতি প্রয়োজন। দেখুন কখন ডাবল-কোটিং দরকার? আরও পুঙ্খানুপুঙ্খ বিশ্লেষণের জন্য।

আপনার অন্যান্য ক্ষেত্রে ডাবল উক্তিগুলি দরকার, বিশেষত export VAR="${VAR1}"(যা সমানভাবে লেখা যেতে পারে export "VAR=${VAR1}") অনেকগুলি শেল (পসিক্স এই ক্ষেত্রে খোলা ছেড়ে দেয়)। সাধারণ কাজগুলির সাথে এই মামলার মিল এবং আপনার ক্ষেত্রে দ্বিগুণ উদ্ধৃতি প্রয়োজন নেই এমন তালিকার বিক্ষিপ্ত প্রকৃতির কারণেই আপনি বিভক্ত হয়ে বিশ্বব্যাপী না চাইলে আমি কেবল ডাবল উদ্ধৃতি ব্যবহারের পরামর্শ দিই।


2
একটি সাধারণ নিয়ম হিসাবে, আমি সর্বদা পরিবর্তনশীল বিস্তৃতি উদ্ধৃত করব যখন আমি জানতাম যে মানটিতে কোনও IFSঅক্ষর থাকবে না কারণ আমি অভ্যাসে থাকতে চাই। একটি ব্যতিক্রম হ'ল ভেরিয়েবল অ্যাসাইনমেন্টটি করার সময় আমি মানটি উদ্ধৃত করি না (প্রয়োজন ব্যতীত, যখন মানটিতে কোনও স্থান থাকে)। কমান্ড বিকল্পগুলি যেমন যেমন থাকে তখন এটি সম্পাদক সিনট্যাক্সকে আরও কার্যকর করে তোলে FOO=$(BAR=$(BAZ=blah; printf %s "${BAZ}"); printf %s "${BAR}")। "স্ট্রিং" রঙের সবকিছু রঙ করার পরিবর্তে আমি নেস্টেড কোডের সিনট্যাক্স হাইলাইট করি। এই কারণেই আমি ব্যাকটিকগুলি এড়িয়ে চলি।
রিচার্ড হ্যানসেন

যদিও >$filePOSIX স্ক্রিপ্ট-এ ঠিক আছে, এটা এমনকি যখন নন-ইন্টারেক্টিভ (যদি না POSIX অনুসরণের সাথে প্রয়োগ করা হয় ব্যাশ নেই $POSIXLY_CORRECTবা --posix...)।
স্টাফেন চেজেলাস

যদিও এটি সত্য যে কোটগুলির প্রয়োজন নেই VAR=$VAR1, আমি মাঝে মাঝে অবাক হয়েছি local VAR=$VAR1, যা আমি কিছুটা ক্ষেত্রে কিছুটা আলাদাভাবে কাজ করার কথা মনে করি some তবে এটিএম, আমি বিচ্ছিন্নতা পুনরুত্পাদন করতে পারি না।
সন্দেহজনক জিম

ঠিক আছে, আমি মনে করছিলাম সেই সমস্যাটি খুঁজে পেয়েছি । এটি কেবল কয়েকটি শাঁসে প্রদর্শিত হয়।
dubiousjim

@ সন্দেহজনক জিম local VAR=$VAR1এর মতো export VAR=$VAR1, এটি শেলের উপর নির্ভর করে।
গিলস

8

উদ্ধৃতি

বিবেচনা করুন যে ডাবল-উদ্ধৃতিটি পরিবর্তনশীল প্রসারণের জন্য ব্যবহৃত হয় এবং একক-উদ্ধৃতিটি দৃ strong়-উদ্ধৃতি হিসাবে ব্যবহার করা হয়, অর্থাত্ সংশ্লেষণের জন্য।

সম্প্রসারণ:

this='foo'
that='bar'
these="$this"
those='$that'

আউটপুট:

for item in "$this" "$that" "$these" "$those"; do echo "$item"; done
foo
bar
foo
$that

এটি উল্লেখ করার উপযুক্ত হতে পারে যে বেশ কয়েকটি কারণে আপনার যেখানেই সম্ভব উদ্ধৃতি ব্যবহার করা উচিত, এর মধ্যে সেরাগুলির মধ্যে এটি সেরা অনুশীলন হিসাবে বিবেচিত এবং পাঠযোগ্যতার জন্য। এছাড়াও যেহেতু বাশ অনেক সময় অদ্ভুত এবং আপাতদৃষ্টিতে অযৌক্তিক বা অযৌক্তিক / অপ্রত্যাশিত উপায়ে, এবং উদ্ধৃতিটি স্পষ্টতই প্রত্যাশিত প্রত্যাশাগুলিকে পরিবর্তিত করে, যা ত্রুটি পৃষ্ঠকে কমিয়ে দেয় (বা এতে সম্ভাবনাময়)।

এবং যদিও উদ্ধৃতি না দেওয়া সম্পূর্ণ আইনী এবং বেশিরভাগ ক্ষেত্রে কাজ করবে, সেই কার্যকারিতাটি সুবিধার জন্য সরবরাহ করা হয়েছে এবং সম্ভবত কম বহনযোগ্য। উদ্দেশ্য এবং প্রত্যাশা প্রতিফলিত করার গ্যারান্টিযুক্ত সম্পূর্ণ-আনুষ্ঠানিক অনুশীলন উদ্ধৃত করা হয়।

প্রতিকল্পন

এখন আরও বিবেচনা করুন যে কনস্ট্রাক্টটি "${somevar}"বিকল্প প্রতিস্থাপনের জন্য ব্যবহৃত হয়। প্রতিস্থাপন এবং অ্যারেগুলির মতো বেশ কয়েকটি ব্যবহারের কেস।

প্রতিস্থাপন (স্ট্রিপিং):

thisfile='foobar.txt.bak'
foo="${thisfile%.*}"   # removes shortest part of value in $thisfile matching after '%' from righthand side
bar="${thisfile%%.*}"  # removes longest matching

for item in "$foo" "$bar"; do echo "$item"; done
foobar.txt
foobar

প্রতিস্থাপন (প্রতিস্থাপন):

foobar='Simplest, least effective, least powerful'
# ${var/find/replace_with}
foo="${foobar/least/most}"   #single occurrence
bar="${foobar//least/most}"  #global occurrence (all)

for item in "$foobar" "$foo" "$bar"; do echo "$item"; done
Simplest, least effective, least powerful
Simplest, most effective, least powerful
Simplest, most effective, most powerful

অ্যারেগুলির:

mkdir temp
# create files foo.txt, bar.txt, foobar.txt in temp folder
touch temp/{foo,bar,foobar}.txt
# alpha is array of output from ls  
alpha=($(ls temp/*))

echo "$alpha"         #  temp/foo.txt
echo "${alpha}"       #  temp/foo.txt
echo "${alpha[@]}"    #  temp/bar.txt  temp/foobar.txt  temp/foo.txt
echo "${#alpha}"      #  12 # length of first element (implicit index [0])
echo "${#alpha[@]}"   #  3  # number of elements
echo "${alpha[1]}"    #  temp/foobar.txt # second element
echo "${#alpha[1])"   #  15 # length of second element

for item in "${alpha[@]}"; do echo "$item"; done
temp/bar.txt
temp/foobar.txt
temp/foo.txt

এগুলি সবই "${var}"সাবস্টিটিউশন কনস্ট্রাক্টের পৃষ্ঠকে সবে স্ক্র্যাচ করছে । বাশ শেল স্ক্রিপ্টিংয়ের সুনির্দিষ্ট রেফারেন্স হ'ল লিব্রে অনলাইন রেফারেন্স, টিএলডিপি লিনাক্স ডকুমেন্টেশন প্রকল্পhttps://www.tldp.org/LDP/abs/html/parameter-substitution.html


1
খুবই তথ্যবহুল.
ওরিওন এলিজিল

0
ls -la

lrwxrwxrwx.  1 root root      31 Nov 17 13:13 prodhostname
lrwxrwxrwx.  1 root root      33 Nov 17 13:13 testhostname
lrwxrwxrwx.  1 root root      32 Nov 17 13:13 justname

তারপরে শেষ:

env=$1
    if [ ! -f /dirname/${env}hostname ]

কার্লিগুলি ব্যবহারের একটি স্পষ্ট উদাহরণ হিসাবে উল্লেখযোগ্য

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