স্থানীয় ভেরিয়েবল অ্যাসাইনমেন্টের জন্য কোটগুলি দরকার?


36

আমি কি কোনও স্থানীয় কার্যভারের ডানদিকে নিরাপদে উদ্ধৃতিগুলি বাদ দিতে পারি?

function foo {
    local myvar=${bar}
    stuff()
}

আমি প্রধানত আগ্রহী bash, তবে অন্যান্য শেলগুলির কোণার ক্ষেত্রে কোনও তথ্য স্বাগত।


আমি মনে করি এটি যদি আপনার ফাংশনে এটির মতো থাকে তবে এটি যদি কোনও লাইনে থাকে তবে তার কোনও ত্রুটি নেই। অ্যাসাইনমেন্টগুলির উদ্ধৃতি দেওয়ার দরকার নেই। দেখুন mpi-sb.mpg.de/dartartments/rg1/teaching/unixffb-ss98/…
jirib

উত্তর:


41

উদ্ধৃতির মধ্যে প্রয়োজন হয় export foo="$var"বা local foo="$var"(অথবা readonly, typeset, declareএবং অন্যান্য পরিবর্তনশীল প্রকাশক কমান্ড ) এ:

  • dash
  • shNetBSD বা এর (এছাড়াও Almquist শেল উপর ভিত্তি করে)।
  • shFreeBSD 'র 9.2 বা তার থেকে বড় (দেখুন 9.3 পরিবর্তন )
  • yash
  • zsh5.1 এর পূর্বে সংস্করণ kshবা shঅনুকরণ সহ (বা export var="$(cmd)"যেখানে zshঅন্যথায় শব্দ বিভাজন করবে (গ্লোব্বিং নয়))।

অন্যথায় পরিবর্তনশীল প্রসারণটি শব্দ বিভাজন এবং / অথবা ফাইলনাম উত্পন্ন হতে পারে অন্য কোনও কমান্ডের সাথে যুক্তি হিসাবে।

এবং এর প্রয়োজন নেই:

  • bash
  • ksh (সমস্ত বাস্তবায়ন)
  • shFreeBSD 'র 9.3 অথবা ঊর্ধ্বতন সংস্করণ এর
  • ব্যস্তবক্সের ছাই ভিত্তিক sh(২০০৫ সাল থেকে)
  • zsh

ইন zsh, অনুকরণ shবা kshঅনুকরণ ব্যতীত , স্প্লিট + গ্লোব কখনই প্যারামিটার বিস্তারের উপর করা হয় না, তবে কমান্ড প্রতিস্থাপনের ভিত্তিতে বিভাজন (গ্লোব নয়) সম্পন্ন হয়। সংস্করণ 5.1, export/ localএবং অন্যান্য ঘোষণাপত্র কমান্ডগুলি উপরের অন্যান্য শেলগুলির মতো দ্বৈত কীওয়ার্ড / বিল্টিন কমান্ডে পরিণত হয়েছে , যার অর্থ উদ্ধৃতিটি প্রয়োজনীয় নয়, এমনকি sh/ kshঅনুকরণ এবং এমনকি কমান্ড প্রতিস্থাপনের জন্যও।

এমন বিশেষ কেস রয়েছে যেখানে এই শেলগুলিতে এমনকি উদ্ধৃতি প্রয়োজন যেমন:

a="b=some value"
export "$a"

বা আরও সাধারণভাবে, যদি এর কিছু বাকী =(সমেত =) উদ্ধৃত হয় বা কিছু সম্প্রসারণের ফলাফল হয় (যেমন export 'foo'="$var", export foo\="$var"বা export foo$((n+=1))="$var"( $((...))এটিও আসলে উদ্ধৃত করা উচিত) ...)। অথবা অন্য কথায় যখন যুক্তিটি exportবৈধ ভেরিয়েবল অ্যাসাইনমেন্ট না হয় যদি এটি ছাড়া লেখা থাকে export

তাহলে export/ localকমান্ডের নাম নিজেই উদ্ধৃত করা হয় (এমনকি মত অংশে "export" a="$b", 'ex'port a="$b", \export a="$b", অথবা এমনকি ""export a="$b"), প্রায় কোট $bযেমন AT & T ছাড়া প্রয়োজন হয় kshএবং mksh

যদি export/ localবা এর কিছু অংশ কিছু বিস্তারের ফলাফল হয় (যেমন cmd=export; "$cmd" a="$b"বা তেমনও export$(:) a="$b") বা এর মতো জিনিসগুলিতে dryrun=; $dryrun export a="$b") তবে প্রতিটি শেলের মধ্যে উদ্ধৃতিগুলি প্রয়োজন।

এর ক্ষেত্রে > /dev/null export a="$b", উদ্ধৃতিগুলি দরকার pdkshএবং এর কিছু ডেরাইভেটিভ রয়েছে।

কারণ command export a="$b", প্রতিটি শেলের মধ্যে উদ্ধৃতিগুলি প্রয়োজন তবে mkshএবং ksh93(একই বিস্তৃতি সম্পর্কে commandএবং exportকিছু বিস্তারের ফলাফল হিসাবে নয়)।

এগুলি লেখার সময় কোনও শেলের প্রয়োজন নেই:

foo=$var export foo

(সেই বাক্য গঠন বর্ন শেলের সাথেও সামঞ্জস্যপূর্ণ তবে সাম্প্রতিক সংস্করণগুলিতে zsh, কেবল যখন sh/ kshঅনুকরণে কাজ করা হয়)।

(মনে রাখবেন যে var=value local varশাঁসগুলির মধ্যে আচরণের পরিবর্তিত হওয়ার কারণে ব্যবহার করা উচিত নয়)।

আরও মনে রাখবেন যে exportকোনও অ্যাসাইনমেন্ট সহ ব্যবহার করার অর্থ হ'ল cmdইন-এর প্রস্থান স্থিতি export var="$(cmd)"হ'ল। export var; var=$(cmd)সমস্যাটি না হওয়ায় এটি করা ।

এছাড়াও এই বিশেষ ক্ষেত্রে থেকে সাবধান bash:

$ bash -c 'IFS=; export a="$*"; echo "$a"' bash a b
ab
$ bash -c 'IFS=; export a=$*; echo "$a"' bash a b
a b

আমার পরামর্শ সর্বদা উদ্ধৃত করা হবে।


3
নোট যে zshউদ্ধৃতি হয় জন্য প্রয়োজনীয় local foo="$(cmd)"কারণ wordsplitting (কিন্তু ফাইলের নাম প্রজন্মের) হয় (কিন্তু unquoted প্যারামিটার প্রসারণও জন্য নয়) unquoted কমান্ড বদল জন্য সঞ্চালিত, যদি না KSH_TYPESETসক্ষম হলে, যা কেস কোট করা হয় না প্রয়োজন। ধারণা তৈরী কর? কোন? আপনি যখন যা করছেন ঠিক কী না তা আপনি যদি না জানেন তবে সর্বদা সব কিছু উদ্ধৃত করুন।
ম্যাট

2
@ ম্যাট, আমি আপনার উপসংহারটি পছন্দ করি। : ডি এটা এর মজার, আমি কি শেল স্ক্রিপ্টিং এর শিখেছি করেছি অধিকাংশ এই stackexchange থেকে এসেছিলেন, যাতে আমি বুঝতে পারেনি যে সবসময় আপনার ভেরিয়েবল উদ্ধৃত হয় না স্ক্রিপ্ট লেখকদের মধ্যে সাধারণ জ্ঞান। আমি খুঁজে পেলাম যে লোকেদের উদ্ধৃতি দেয়নি , এবং তারা কী করছে ঠিক কী তা জানে না এমন লোকেদের দ্বারা রচিত বিদ্যমান প্রোডাক্ট স্ক্রিপ্টগুলি করার জন্য আমার অনেক কিছু ঠিক করার দরকার আছে ....
ওয়াইল্ডকার্ড

3

আমি সাধারণত ভেরিয়েবলগুলির যে কোনও ব্যবহারের কথা উদ্ধৃত করি যেখানে সাদা স্পেসের মতো অক্ষর থাকতে পারে। অন্যথায় আপনি এই জাতীয় সমস্যার মধ্যে চলে যাবেন:

#!/bin/bash

bar="hi bye"

function foo {
  local myvar=${bar}
  printf "%s\n" $myvar
  printf "%s\n" "$myvar"
}

foo

কোনও কার্যক্রমে ভেরিয়েবলের ব্যবহারের উদ্ধৃতিগুলির প্রয়োজন মনে হয় না, তবে আপনি যখন এটি ব্যবহার করতে যান তবে printfআপনাকে সেখানে উদ্ধৃত করা দরকার:

  printf "%s\n" "$myvar"

দ্রষ্টব্য: মনে রাখবেন যে ভেরিয়েবলটি $IFSবিভাজক অক্ষরগুলি কী তা নিয়ন্ত্রণ করে।

IFS    The  Internal  Field  Separator that is used for word splitting after 
       expansion and to split lines into words with the read builtin command. 
       The default value is ``<space><tab><newline>''.

উদাহরণ

বাশে ডিবাগিং সক্ষম করে আমরা পর্দার আড়ালে কী ঘটছে তা দেখতে পাচ্ছি।

$ bash -x cmd.bash 
+ bar='hi bye'
+ foo
+ local 'myvar=hi bye'
+ printf '%s\n' hi bye
hi
bye
+ printf '%s\n' 'hi bye'
hi bye

উপরের অংশে আমরা দেখতে পাচ্ছি যে পরিবর্তনশীলটিকে $barসূক্ষ্ম হাতে তুলে দেওয়া হয়েছিল $myvarতবে আমরা যখন ব্যবহার করতে $myvarযাই তখন যখন আমরা $myvarএটি ব্যবহার করতে গিয়েছিলাম তখন এর বিষয়বস্তুগুলির জ্ঞানীয় হতে হয়েছিল ।


2
শব্দ বিভাজন unquoted ভেরিয়েবল সঙ্গে একমাত্র সমস্যা না হয় তবে আপনি বিবেচনা করতে ফাইলের নাম প্রজন্মের (ওরফে globbing) পাশাপাশি (যদিও যে (উভয়) পরিবর্তনশীল বরাদ্দকরণ এবং জন্য প্রযোজ্য নয় আছে bashএবং kshlocal/ typeset... বিশেষ builtins)।
স্টাফেন চ্যাজেলাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.