শেল কার্যক্রমে স্থানীয় ভেরিয়েবলের সুযোগ


28

24.2 পড়ার পরে স্থানীয় ভেরিয়েবল , আমি ভেবেছিলাম varকীওয়ার্ডের সাহায্যে ভেরিয়েবল ঘোষণার localঅর্থ এই যে varকোনও ক্রমের কোঁকড়ানো ধনুর্বন্ধনী দ্বারা সীমিত কোডের ব্লকের মধ্যেই এর মানটি অ্যাক্সেসযোগ্য।

যাইহোক, নিম্নলিখিত উদাহরণে চলমান পরে, আমি বুঝতে পারলাম যে varএছাড়াও, অ্যাক্সেস করা যেতে পারে পড়া এবং ফাংশন কোড যে ব্লক দ্বারা প্রার্থনা লিখিত - অর্থাৎ যদিও varঘোষিত হয় localথেকে outerFunc, innerFuncএখনও এটা পড়তে এবং এর মান পরিবর্তন করতে সক্ষম হয়।

Run It Online

#!/usr/bin/env bash

function innerFunc() {
    var='new value'
    echo "innerFunc:                   [var:${var}]"
}

function outerFunc() {
    local var='initial value'

    echo "outerFunc: before innerFunc: [var:${var}]"
    innerFunc
    echo "outerFunc: after  innerFunc: [var:${var}]"
}

echo "global:    before outerFunc: [var:${var}]"
outerFunc
echo "global:    after  outerFunc: [var:${var}]"

আউটপুট:

global:    before outerFunc: [var:]               # as expected, `var` is not accessible outside of `outerFunc`
outerFunc: before innerFunc: [var:initial value]
innerFunc:                   [var:new value]      # `innerFunc` has access to `var` ??
outerFunc: after  innerFunc: [var:new value]      # the modification of `var` by `innerFunc` is visible to `outerFunc` ??
global:    after  outerFunc: [var:]

প্রশ্ন: এটি কি আমার শেলের একটি বাগ (বাশ 4.3.42, উবুন্টু 16.04, 64 বিট) বা এটি প্রত্যাশিত আচরণ?

সম্পাদনা: সমাধান করা হয়েছে। @ মার্কপ্লটনিক দ্বারা উল্লিখিত হিসাবে এটি অবশ্যই প্রত্যাশিত আচরণ।


এটি প্রত্যাশিত আচরণ
এফএমপিআরফি

2
আমি কি কেবলমাত্র যিনি এটিকে অদ্ভুত মনে করেন যে আউটপুটটির শেষ লাইনে মানটি varখালি? varবিশ্বব্যাপী সেট করা আছে innerFunc, সুতরাং স্ক্রিপ্টের শেষ না হওয়া পর্যন্ত এটি কেন আটকে থাকবে না?
হ্যারল্ড ফিশার

উত্তর:


22

শেল ভেরিয়েবলগুলির একটি গতিশীল সুযোগ রয়েছে । যদি কোনও ফাংশনে কোনও ভেরিয়েবল স্থানীয় হিসাবে ঘোষিত হয় তবে ফাংশনটি ফিরে না আসা পর্যন্ত সেই সুযোগটি রয়ে যায়।

দুটি ব্যতিক্রম আছে:

  1. ksh93 এ, যদি কোনও ফাংশনটি স্ট্যান্ডার্ড function_name () { … }সিনট্যাক্সের সাথে সংজ্ঞায়িত করা হয় , তবে এর স্থানীয় ভেরিয়েবলগুলি গতিশীল স্কোপিং মান্য করে। তবে যদি কোনও ফাংশন কেএসএস সিনট্যাক্সের সাথে সংজ্ঞায়িত করা হয় function function_name { … }তবে এর স্থানীয় ভেরিয়েবল লেক্সিকাল / স্ট্যাটিক স্কোপিং মান্য করে, তাই এগুলি দ্বারা ডাকা অন্য ফাংশনে তারা দৃশ্যমান হয় না।

  2. zsh/privateমধ্যে autoloadable প্লাগইন zshএকটি প্রদান করে privateশব্দ / builtin স্ট্যাটিক সুযোগ সঙ্গে একটি ভেরিয়েবল ডিক্লেয়ার করতে ব্যবহার করা যেতে পারে।

ছাই, বাশ, পিডিএক্স এবং ডেরিভেটিভস, বশের কেবল গতিশীল স্কোপিং রয়েছে।


শেলের সমস্ত ভেরিয়েবলের কি ডায়নামিক স্কোপ থাকে বা এটি কেবল ঘোষিত ভেরিয়েবলের ক্ষেত্রে প্রযোজ্য local?
হ্যারল্ড ফিশার

@ হারল্ডফিশার সমস্ত ভেরিয়েবলের গতিশীল সুযোগ রয়েছে। একটি সঙ্গে typesetবা declareবা localঘোষণা, সুযোগ ফাংশন আয় পর্যন্ত হয়। এ জাতীয় ঘোষণা ছাড়াই সুযোগটি বিশ্বব্যাপী।
গিলস

6

এটি কোনও বাগ নয়, বহিরাগতের প্রসঙ্গে অভ্যন্তরীণ কলটি $ var এর স্থানীয় কপি ব্যবহার করে। আউটফুঙ্কের "স্থানীয়" অর্থ গ্লোবাল পরিবর্তন হয়নি। যদি আপনি আউটআরফঙ্কের বাইরের ইনফরঙ্ককে কল করেন তবে বৈশ্বিক $ var এ পরিবর্তন হবে, তবে বহিরঙ্গনীর স্থানীয় $ var নয়। যদি আপনি ইনটারনফঙ্কে "স্থানীয়" যোগ করেন তবে আউটফুঙ্কের $ বর্ণটি পরিবর্তন করা যাবে না - সংক্ষেপে, এর মধ্যে 3 টি থাকবেন:

  • $ বিশ্বব্যাপী :: Var
  • $ OuterFunc :: Var
  • $ InnerFunc :: Var

পার্লের নেমস্পেস ফর্ম্যাটটি ব্যবহার করতে, সাজানো।


2

স্থানীয় সুযোগকে বাধ্য করার জন্য আপনি একটি ফাংশন ব্যবহার করতে পারেন:

sh_local() {
  eval "$(set)" command eval '\"\$@\"'
}

উদাহরণ:

x() {
  z='new value'
  printf 'function x, z = [%s]\n' "$z"
}
y() {
  z='initial value'
  printf 'function y before x, z = [%s]\n' "$z"
  sh_local x
  printf 'function y after x, z = [%s]\n' "$z"
}
printf 'global before y, z = [%s]\n' "$z"
y
printf 'global after y, z = [%s]\n' "$z"

ফলাফল:

global before y, z = []
function y before x, z = [initial value]
function x, z = [new value]
function y after x, z = [initial value]
global after y, z = [initial value]

সূত্র


2

ইন হিসেবে ঘোষণা করা হয় নি স্থানীয় অতএব এটি উপলব্ধ প্রোফাইল সুযোগ (একবার ফাংশন বলা হয়েছে)। function innerFunc()var='new value'

বিপরীতভাবে, মধ্যে হিসাবে মনোনীত হন স্থানীয় অতএব এটা বিশ্বব্যাপী সুযোগ (এমনকি যদি ফাংশন বলা হয়েছে) এ উপলব্ধ।function outerFunc()local var='initial value'

কারণ innerFunc()এটি একটি শিশু হিসাবে ডাকা হত outerFunc(), var স্থানীয় স্থানীয় ক্ষেত্রের মধ্যে outerFunc()

man 1 bash স্পষ্ট করতে সাহায্য করতে পারে

স্থানীয় [বিকল্প] [নাম [= মান] ...]

প্রতিটি যুক্তির জন্য, স্থানীয় ভেরিয়েবল নামের নাম তৈরি করা হয়, এবং নির্ধারিত মান। বিকল্পটি ঘোষণার মাধ্যমে গৃহীত বিকল্পগুলির মধ্যে যে কোনও হতে পারে। স্থানীয় যখন কোনও ফাংশনের মধ্যে ব্যবহার করা হয়, তখন এটি ভেরিয়েবলের নামটি সেই ফাংশন এবং তার বাচ্চাদের মধ্যে একটি দৃশ্যমান সুযোগ সীমাবদ্ধ করে দেয়। ...

উহ্য আচরণ বর্ণনাতে আশা করা হচ্ছে ঘোষণা করে অর্জন করা যেতে পারে local var='new valueযে function innerFunc()

অন্যরা যেমন বলেছে, এটি ব্যাশ শেলের কোনও বাগ নয়। সবকিছু যেমনটি করা উচিত তেমন কাজ করে।


আপনার প্রথম বিবৃতিটি ব্যবহারকারী যা দেখছে তার বিপরীতে। varবৈশ্বিক সুযোগে মানটির মুদ্রণ , innerFuncমাধ্যমে কল করার পরে outFunc, মুদ্রণ হয় না new value
কুসালানন্দ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.