স্কোপগুলি শেল ভেরিয়েবলগুলি কী থাকতে পারে?


42

আমি কেবল একটি সমস্যার মধ্যে দৌড়েছি যা আমাকে দেখায় আমি শেল ভেরিয়েবলের পরিধি সম্পর্কে পরিষ্কার নই।

আমি চেষ্টা করার চেষ্টা করছিলাম bundle install, এটি একটি রুবি কমান্ড যা $GEM_HOMEএর কাজটি করার মান ব্যবহার করে । আমি সেট করে দিয়েছি $GEM_HOME, তবে কমান্ডটি যতক্ষণ না ব্যবহার করেছি ততক্ষণ এই মানটিকে উপেক্ষা exportকরেছে export GEM_HOME=/some/path

আমি পড়েছি যে এটি কোনওভাবে বৈকল্পিককে "বৈশ্বিক" করে তোলে ( পরিবেশগত পরিবর্তনশীল হিসাবেও পরিচিত ), তবে এর অর্থ কী তা আমি বুঝতে পারি না। আমি প্রোগ্রামিংয়ে গ্লোবালগুলি সম্পর্কে জানি, তবে আলাদা প্রোগ্রামগুলিতে নয়।

এছাড়াও, আমার সেটিংসের এই পরিবর্তনগুলি কেবল বর্তমান শেল সেশনেই প্রযোজ্য, আমি কীভাবে সেগুলি ডিমনাইজড প্রক্রিয়া হিসাবে সেট করব?

স্কোপগুলি শেল ভেরিয়েবলগুলি কী থাকতে পারে?

উত্তর:


33

প্রসেস একটি গাছ মত করে সাজানো হয়: প্রতি প্রক্রিয়া একটি অনন্য পিতা বা মাতা, ছাড়া হয়েছে initযা PIDসর্বদা 1 এবং কোন পিতা বা মাতা হয়েছে।

একটি নতুন প্রক্রিয়া তৈরি করা সাধারণত fork/ জুড়ি execvকল / সিস্টেম কলের মধ্য দিয়ে যায় , যেখানে শিশু প্রক্রিয়ার পরিবেশটি পিতামাতার প্রক্রিয়ার একটি অনুলিপি

আপনার যে শেলটি রয়েছে সেগুলি থেকে পরিবেশে একটি পরিবর্তনশীল রাখার জন্য exportসেই পরিবর্তনশীলটি যাতে এটি সমস্ত বাচ্চার কাছে পুনরাবৃত্তভাবে দৃশ্যমান হয়। তবে সচেতন থাকুন যে কোনও শিশু যদি কোনও ভেরিয়েবলের মান পরিবর্তন করে তবে পরিবর্তিত মানটি কেবল এটির জন্য দৃশ্যমান এবং সেই পরিবর্তনের পরে তৈরি সমস্ত প্রক্রিয়া ( যেমন আগে বলা হয়েছিল অনুলিপি হ'ল )।

এটিকেও বিবেচনায় রাখুন যে কোনও শিশু প্রক্রিয়া তার পরিবেশ পরিবর্তন করতে পারে, উদাহরণস্বরূপ এটি সম্ভবত ডিফল্ট মানগুলিতে পুনরায় সেট করতে পারে login


1
আহ! ঠিক আছে, আসুন দেখুন আমি এটি বুঝতে পারি কিনা। শেলটিতে, যদি আমি বলি FOO=bar, এটি বর্তমান শেল প্রক্রিয়াটির জন্য মান নির্ধারণ করে। আমি যদি তখন ( bundle install) এর মতো কোনও প্রোগ্রাম পরিচালনা করি তবে এটি একটি শিশু প্রক্রিয়া তৈরি করে, যা অ্যাক্সেস পায় না FOO। তবে আমি যদি বলতাম export FOO=bar, শিশু প্রক্রিয়াটি (এবং এর বংশধরেরা) এতে অ্যাক্সেস করতে পারে। এর মধ্যে একটি export FOO=buzzতার পরিবর্তে তার বংশধরদের জন্য মান পরিবর্তন করতে বা কেবল FOO=buzzনিজের জন্য মান পরিবর্তন করার জন্য কল করতে পারে। এটা কি ঠিক?
নাথান লং

2
@ নাথানলং এটি ঠিক এটি নয়: সমস্ত আধুনিক শেলের মধ্যে একটি পরিবর্তনশীল হয় রফতানি হয় (এবং সুতরাং মানের কোনও পরিবর্তন বংশধরের পরিবেশে প্রতিফলিত হয়) বা রফতানি হয় না (অর্থাত্ পরিবর্তনশীল পরিবেশে নয়)। বিশেষত, শেলটি শুরু হওয়ার সাথে যদি ভেরিয়েবলটি ইতিমধ্যে পরিবেশে থাকে তবে তা রফতানি করা হয়।
গিলস 'অসন্তুষ্ট হওয়া বন্ধ করুন'

2
"একটি শিশু যদি একটি ভেরিয়েবলের মান পরিবর্তন করে তবে পরিবর্তিত মানটি কেবল এটির জন্য দৃশ্যমান এবং পরিবর্তনের পরে তৈরি সমস্ত প্রক্রিয়া" বাক্যটি দ্বারা আমি কিছুটা বিভ্রান্ত হয়ে পড়েছিলাম। "... এটির পক্ষে দৃশ্যমান এবং এর পরিবর্তনের পরে তৈরি হওয়া তার বংশধরগুলির সমস্ত প্রক্রিয়া" বলা আরও সঠিক হবে - পিতামাতার প্রক্রিয়াটির অন্যান্য শিশুরা এমনকি শিশু প্রক্রিয়াটির পরে শুরু হওয়া শিশুরাও প্রভাবিত হয় না।
জান

26

কমপক্ষে kshএবং এর অধীনে bash, ভেরিয়েবলের তিনটি স্কোপ থাকতে পারে, বাকি সমস্ত উত্তরের মতো দুটি বর্তমানে বলছে।

রফতানি করা (যেমন পরিবেশ) ভেরিয়েবল এবং শেল অপরিবর্তিত ভেরিয়েবল স্কোপগুলি ছাড়াও ফাংশন স্থানীয় ভেরিয়েবলের জন্য তৃতীয় সংকীর্ণ রয়েছে।

typesetটোকেন সহ শেল ফাংশনগুলিতে ঘোষিত চলকগুলি সেখান থেকে ডাকা এবং (উপ) ফাংশনগুলির মধ্যে কেবল ঘোষিত ফাংশনের ভিতরেই দৃশ্যমান।

এই ksh/ bashকোড:

# Create a shell script named /tmp/show that displays the scoped variables values.    
echo 'echo [$environment] [$shell] [$local]' > /tmp/show
chmod +x /tmp/show

# Function local variable declaration
function f
{
    typeset local=three
    echo "in function":
    . /tmp/show 
}

# Global variable declaration
export environment=one

# Unexported (i.e. local) variable declaration
shell=two

# Call the function that creates a function local variable and
# display all three variable values from inside the function
f

# Display the three values from outside the function
echo "in shell":
. /tmp/show 

# Display the same values from a subshell
echo "in subshell":
/tmp/show

# Display the same values from a disconnected shell (simulated here by a clean environment start)
echo "in other shell"
env -i /tmp/show 

এই আউটপুট উত্পাদন করে:

in function:
[one] [two] [three]
in shell:
[one] [two] []
in subshell:
[one] [] []
in other shell
[] [] []

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

মনে রাখবেন যে এই আধুনিক আচরণটি উইন্ডোজের থেকে সম্পূর্ণ আলাদা যেখানে আপনি সিস্টেমের ভেরিয়েবলগুলি ব্যবহার করতে পারেন যা পুরো বিশ্বজুড়ে এবং সমস্ত প্রক্রিয়া দ্বারা ভাগ করা আছে।


12

তারা প্রক্রিয়া দ্বারা scoped হয়

অন্যান্য উত্তরদাতারা আমাকে বুঝতে সাহায্য করেছিল যে শেল ভেরিয়েবলের সুযোগগুলি প্রক্রিয়া এবং তাদের বংশধর সম্পর্কে ।

আপনি যখন lsকমান্ড লাইনের মতো একটি কমান্ড টাইপ করেন , আপনি আসলে lsপ্রোগ্রামটি চালানোর জন্য একটি প্রক্রিয়াটি তৈরি করছেন । নতুন প্রক্রিয়াটিতে এটির পিতামাতা হিসাবে আপনার শেল রয়েছে।

যে কোনও প্রক্রিয়ার নিজস্ব "স্থানীয়" ভেরিয়েবল থাকতে পারে, যা শিশু প্রক্রিয়াগুলিতে পাস হয় না। এটি "এনভায়রনমেন্ট" ভেরিয়েবলও সেট করতে পারে, যা। ব্যবহার exportপরিবেশের পরিবর্তনশীল তৈরি করে । উভয় ক্ষেত্রেই, সম্পর্কিত না হওয়া প্রক্রিয়াগুলি (আসল অংশের সমকক্ষরা) চলকটি দেখতে পাবে না; আমরা কেবল শিশু প্রক্রিয়াগুলি যা দেখি তা নিয়ন্ত্রণ করি।

ধরুন আপনি একটি ব্যাশ শেল, যা আমরা উ: আপনি টাইপ ডাকবো আছে bash, যা একটি শিশু প্রক্রিয়া ব্যাশ শেল, যা আমরা বি যেকোনো কিছু ডাকবো তোমাকে ডেকেছিলাম সৃষ্টি exportএখনো বি সেট হবে উপর

এখন, খ, আপনি বলেন FOO=b। দুই জিনিস এক ঘটবে:

  • যদি বি (এ থেকে) নামক পরিবেশের পরিবর্তনশীল না পেয়ে থাকে তবে FOOএটি একটি স্থানীয় ভেরিয়েবল তৈরি করে। বি এর বাচ্চারা এটি পাবে না (খ কল না দিলে export)।
  • তাহলে বি হয়নি (একটি থেকে) গ্রহণ একটি পরিবেশ পরিবর্তনশীল callled FOO, এটা হবে এটি নিজে এবং তার পরবর্তীকালে forked শিশুদের জন্য সংশোধন । বি এর সন্তানরা যে মূল্য নির্ধারণ করবে তা দেখবে। তবে এটি এটিকে মোটেও প্রভাব ফেলবে না।

এখানে একটি দ্রুত ডেমো রয়েছে।

FOO=a      # set "local" environment variable
echo $FOO  # 'a'
bash       # forks a child process for the new shell
echo $FOO  # not set
exit       # return to original shell
echo $FOO  # still 'a'

export FOO # make FOO an environment variable
bash       # fork a new "child" shell
echo $FOO  # outputs 'a'
FOO=b      # modifies environment (not local) variable
bash       # fork "grandchild" shell
echo $FOO  # outputs 'b'
exit       # back to child shell
exit       # back to original shell
echo $FOO  # outputs 'a'

এগুলি সমস্তই আমার আসল সমস্যাটি ব্যাখ্যা করে: আমি GEM_HOMEআমার শেলটি সেট করেছিলাম, কিন্তু যখন আমি ফোন করেছি bundle install, এটি একটি শিশু প্রক্রিয়া তৈরি করেছে। যেহেতু আমি ব্যবহার করি নি export, শিশু প্রক্রিয়াটি শেলটি পায় নি GEM_HOME

আন রপ্তানি

আপনি একটি পরিবর্তনশীল "আন-এক্সপোর্ট" করতে পারেন - এটি ব্যবহার করে বাচ্চাদের কাছে পৌঁছে দেওয়া থেকে রোধ করতে পারেন export -n FOO

export FOO=a   # Set environment variable
bash           # fork a shell
echo $FOO      # outputs 'a'
export -n FOO  # remove environment var for children
bash           # fork a shell
echo $FOO      # Not set
exit           # back up a level
echo $FOO      # outputs 'a' - still a local variable

1
আপনি যখন বলেন "এটি এটি নিজের এবং তার বাচ্চাদের জন্য এটি সংশোধন করবে" আপনার পরিষ্কার করা উচিত যে পরিবর্তনের পরে তৈরি করা শিশুরা কেবল পরিবর্তিত মানটি দেখতে পাবে।
enzotib

1
@ এঞ্জোটিব - ভাল কথা আপডেট করা হয়েছে।
নাথান লং

3

রফতানি সম্পর্কে আমি যে সর্বোত্তম ব্যাখ্যা খুঁজে পেতে পারি তা হ'ল:

http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_02.html

একটি সাব-শেল বা চাইল্ড শেলের মধ্যে পরিবর্তনশীল সেটটি কেবল সাব-শেলটিতে দৃশ্যমান যেখানে এটি সংজ্ঞায়িত হয়েছে। রফতানযোগ্য ভেরিয়েবলটি আসলে পরিবেশের পরিবর্তনশীল হিসাবে তৈরি। সুতরাং পরিষ্কার করার জন্য আপনার bundle installনিজের শেলটি কার্যকর করে যা $GEM_HOMEএটি environmentপরিবর্তনশীল ওরফে রফতানি করা না হলে দেখতে পাবে না ।

আপনি এখানে পরিবর্তনশীল সুযোগের জন্য ডকুমেন্টেশনগুলি একবার দেখে নিতে পারেন:

http://www.tldp.org/LDP/abs/html/subshells.html


আহ, সুতরাং আমি "এনভায়রনমেন্ট ভেরিয়েবল" শব্দটি ব্যবহার করতে ভুল ছিলাম FOO=bar; exportএটি তৈরি করতে আপনাকে ব্যবহার করতে হবে। প্রশ্ন অনুসারে সংশোধন করা হয়েছে।
নাথান লং

আমি যুক্ত করা লিঙ্কটি একবার দেখুন
কার্লসন

3

প্রত্যাশার মতো পরিবর্তনশীল স্কোপগুলির একটি শ্রেণিবিন্যাস রয়েছে।

পরিবেশ

বাইরেরতম সুযোগটি পরিবেশ। এটি কেবলমাত্র অপারেটিং সিস্টেম দ্বারা পরিচালিত স্কোপ এবং তাই প্রতিটি প্রক্রিয়াটির জন্য এটির গ্যারান্টিযুক্ত। যখন কোনও প্রক্রিয়া শুরু হয় তখন এটি তার পিতামাতার পরিবেশের একটি অনুলিপি গ্রহণ করে যার পরে দু'জন স্বতন্ত্র হয়: সন্তানের পরিবেশ পরিবর্তন করা পিতামাতার পরিবর্তন করে না, এবং পিতামাতার পরিবেশ পরিবর্তন করা ইতিমধ্যে বিদ্যমান সন্তানের পরিবর্তিত হয় না।

শেল ভেরিয়েবল

শেলগুলির ভেরিয়েবলগুলির নিজস্ব ধারণা রয়েছে। এখান থেকেই জিনিসগুলি কিছুটা বিভ্রান্ত হয়ে উঠতে শুরু করে।

আপনি যখন শেলের কোনও ভেরিয়েবলকে একটি মান নির্ধারণ করেন এবং পরিবেশে ইতিমধ্যে সেই পরিবর্তনশীল উপস্থিত থাকে তখন পরিবেশ ভেরিয়েবলটি নতুন মানটি গ্রহণ করে। তবে যদি ভেরিয়েবলটি পরিবেশে না থাকে তবে এটি শেল ভেরিয়েবলে পরিণত হয়। শেল প্রক্রিয়া কেবল শেল প্রক্রিয়ার মধ্যেই থাকে, যেমন রুবি স্ক্রিপ্টগুলির মধ্যে কেবল রুবি ভেরিয়েবলগুলি বিদ্যমান। এগুলি কখনও শিশু প্রক্রিয়া দ্বারা উত্তরাধিকার সূত্রে প্রাপ্ত হয় না।

মূল exportশব্দটি খেলতে আসে যেখানে এখানে । এটি শেল প্রক্রিয়াটির পরিবেশে একটি শেল পরিবর্তনশীল অনুলিপি করে যাতে শিশু প্রক্রিয়াগুলি উত্তরাধিকার সূত্রে সম্ভব করে।

স্থানীয় পরিবর্তনশীল

স্থানীয় ভেরিয়েবলগুলি শেল ভেরিয়েবলগুলি এতে থাকা কোড ব্লকগুলিতে স্কোপ করা হয়। আপনি typesetকীওয়ার্ড (পোর্টেবল) localবা declare(বাশ) দিয়ে স্থানীয় ভেরিয়েবলগুলি ঘোষণা করেন । অন্যান্য শেল ভেরিয়েবলের মতো স্থানীয় ভেরিয়েবলগুলি শিশু প্রক্রিয়া দ্বারা উত্তরাধিকার সূত্রে প্রাপ্ত হয় না। স্থানীয় চলকগুলিও রফতানি করা যায় না।

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