শেল ভেরিয়েবল এবং এনভায়রনমেন্ট ভেরিয়েবলের মধ্যে ব্যবহারের পার্থক্য কী?


16

আমি আসলে জানতাম না যে কমান্ড লাইন থেকে দুটি ভিন্ন ধরণের ভেরিয়েবল অ্যাক্সেস করতে পারি। আমি কেবল জানতাম, আমি ভেরিয়েবলের মতো ঘোষণা করতে পারি:

foo="my dear friends"
bar[0]="one"
bar[1]="two"
bar[2]="three"

বা একটি চিহ্ন হিসাবে তাদের অ্যাক্সেস, যেমন:

echo $foo
echo ${bar[1]}

বা ইনবিল্ট ভেরিয়েবল ব্যবহার করে, যেমন:

echo $PWD
PATH=$PATH:"/usr/bin/myProg"

এখন, শুনলাম দুটি (কমপক্ষে?) ধরণের ভেরিয়েবল রয়েছে: শেল ভেরিয়েবল এবং এনভায়রনমেন্ট ভেরিয়েবল।

  • দুটি ভিন্ন ধরণের থাকার উদ্দেশ্য কী?
  • ভেরিয়েবল কোন প্রকারের তা আমি কীভাবে জানব?
  • প্রত্যেকের জন্য সাধারণ ব্যবহারগুলি কী কী?


উত্তর:


14

পরিবেশের ভেরিয়েবলগুলি জোড়গুলির তালিকা name=valueরয়েছে যা প্রোগ্রামটি যাই হোক না কেন বিদ্যমান (শেল, অ্যাপ্লিকেশন, ডেমন…)। এগুলি সাধারণত বাচ্চাদের প্রক্রিয়াগুলির দ্বারা উত্তরাধিকার সূত্রে প্রাপ্ত হয় (একটি fork/ execক্রম দ্বারা তৈরি ): শিশুদের প্রক্রিয়াগুলি প্যারেন্ট ভেরিয়েবলগুলির নিজস্ব অনুলিপি পান।

শেল পরিবর্তনশীল কেবল শেলের প্রসঙ্গেই বিদ্যমান। এগুলি কেবল সাবশেলে উত্তরাধিকারসূত্রে প্রাপ্ত (যেমন শেলটি যখন execঅপারেশন ছাড়াই কাঁটা হয়)। শেল বৈশিষ্ট্যগুলির উপর নির্ভর করে, ভেরিয়েবলগুলি কেবল পরিবেশের মতো সাধারণ স্ট্রিংই না হতে পারে অ্যারে, যৌগিক, টাইপযুক্ত ভেরিয়েবলগুলি যেমন পূর্ণসংখ্যা বা ভাসমান পয়েন্ট ইত্যাদি might

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

অ্যারে এবং অন্যান্য জটিল ধরণের ভেরিয়েবলগুলি তাদের নাম এবং মানটি name=valueপ্যাটার্নে রূপান্তর না করা বা এক্সপ্লোর করা যায় না যদি শেল নির্দিষ্ট পদ্ধতিতে থাকে (যেমন: bashপরিবেশে রফতানি ফাংশন এবং কিছু বহিরাগত, পজিক্সহীন শেল পছন্দ করে rcএবং esঅ্যারে রফতানি করতে পারে না) )।

সুতরাং এনভায়রনমেন্ট ভেরিয়েবল এবং শেল ভেরিয়েবলের মধ্যে প্রধান পার্থক্য হ'ল এনভায়রনমেন্ট ভেরিয়েবলগুলি বিশ্বব্যাপী, যখন রফতানি না হওয়া শেল ভেরিয়েবলগুলি স্ক্রিপ্টের স্থানীয় হয়।

আরও মনে রাখবেন যে আধুনিক শেলগুলি (কমপক্ষে kshএবং bash) তৃতীয় শেল ভেরিয়েবল স্কোপ সমর্থন করে। typesetকীওয়ার্ড সহ ফাংশনগুলিতে তৈরি ভেরিয়েবলগুলি সেই ফাংশনের স্থানীয় (ফাংশনটি যেভাবে ঘোষণা করা হয় তার অধীনে এই বৈশিষ্ট্যটিকে সক্ষম / অক্ষম করে তোলে ksh, এবং অধ্যবসায়ের আচরণ bashএবং এর মধ্যে পৃথক হয় ksh)। Https://unix.stackexchange.com/a/28349/2594 দেখুন

1 এই প্রযোজ্য আধুনিক শাঁস পছন্দ ksh, dash, bashএবং অনুরূপ। উত্তরাধিকার বোর্ন শেল এবং নন বোর্ন সিনট্যাক্স শেলের মতো cshআলাদা আচরণ রয়েছে।


1
শিশুরা তাদের পিতামাতার একটি কাঁটাচামচ (একটি সঠিক অনুলিপি) হিসাবে তৈরি করা হওয়ায় শিশুদের সমস্ত প্রক্রিয়া উত্তরাধিকারসূত্রে প্রাপ্ত। বিভিন্ন পরিবেশের সঙ্গে বিন্দু যে তারা প্রেরণ করা হয় execve(), যাতে (সাধারণত) মাধ্যমে ডেটা জিদ করতে ব্যবহার করা হয় সিস্টেম কল সঞ্চালনের অন্যান্য কম্যান্ডের (একই প্রক্রিয়ায়)।
স্টাফেন চেজেলাস

সমস্ত পরিবেশের ভেরিয়েবলগুলি শেল ভেরিয়েবলগুলিতে অনুবাদ হয় না। কেবলমাত্র সেগুলি যা শেল ভেরিয়েবলের নাম হিসাবে বৈধ (এবং IFSকিছু শেলের মতো কিছু ব্যতিক্রম সহ )।
স্টাফেন চেজেলাস

শেলগুলি rc, esঅ্যাডহক এনকোডিং ব্যবহার করে অ্যারে রফতানি করতে পারে। bashএবং rcপরিবেশের ভেরিয়েবলগুলি (আবার একটি বিশেষ এনকোডিং ব্যবহার করে) ব্যবহার করে রফতানিও রফতানি করতে পারে।
স্টাফেন চেজেলাস

ইন ksh93, typesetশুধুমাত্র এর সাথে ঘোষিত কার্যগুলিতে সুযোগকে সীমাবদ্ধ করেfunction foo { ...; } সিনট্যাক্সের বাউর্ন ( foo() cmd) সিনট্যাক্সের সাথে নয় (এবং এটি অন্যান্য শেলের মতো গতিশীল নয়) স্ট্যাটিক স্কোপিংয়ে
স্টাফেন চেজেলাস

@ স্টাফেনচাজেলাস পর্যালোচনা করার জন্য ধন্যবাদ! আপনার মন্তব্যগুলি আমলে নেওয়ার জন্য উত্তর আপডেট করুন।
jlliagre

17

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

শেল ভেরিয়েবলগুলি এমন ভেরিয়েবল যাগুলির স্কোপ বর্তমান শেল সেশনে রয়েছে, উদাহরণস্বরূপ একটি ইন্টারেক্টিভ শেল সেশন বা স্ক্রিপ্টে।

আপনি অব্যক্ত নামটিতে একটি মান নির্ধারণ করে শেল ভেরিয়েবল তৈরি করতে পারেন:

var="hello"

শেল ভেরিয়েবলের ব্যবহার হ'ল বর্তমান সেশনে ডেটা ট্র্যাক করা। শেল ভেরিয়েবলের সাধারণত লোয়ার-কেস অক্ষরের নাম থাকে।

পরিবেশের পরিবর্তনশীল

পরিবেশের পরিবর্তনশীল হ'ল শেল ভেরিয়েবল যা রফতানি করা হয়েছে। এর অর্থ এটি কেবলমাত্র এটি তৈরি করা শেল সেশনেই নয়, যে অধিবেশন থেকে শুরু হওয়া কোনও প্রক্রিয়া (কেবল শাঁস নয়) এর ক্ষেত্রেও এটি একটি চলক হিসাবে দৃশ্যমান হবে।

VAR="hello"  # shell variable created
export VAR   # variable now part of the environment

অথবা

export VAR="hello"

একবার একটি শেল পরিবর্তনশীল রপ্তানি করা হয়েছে, এটা রপ্তানি থাকে না হওয়া পর্যন্ত সেট করা থাকে না, অথবা পর্যন্ত তার "রপ্তানি সম্পত্তি" (সঙ্গে মুছে ফেলা হবে export -nমধ্যে bash), তাই সাধারণত পুনরায় রপ্তানি এটা কোন প্রয়োজন নেই। কোনও ভেরিয়েবলটিকে unsetমুছে ফেলার সাথে এটি সেট করে দেওয়া (এটি পরিবেশের পরিবর্তনশীল কিনা তা বিবেচনা করে নয়)।

অ্যারে এবং এসোসিয়েটিভ হ্যাশ ইন bashএবং অন্যান্য শেলগুলি পরিবেশ পরিবর্তনশীল হয়ে উঠতে রফতানি করা যাবে না। পরিবেশের ভেরিয়েবলগুলি অবশ্যই সরল ভেরিয়েবল হতে হবে যার মানগুলি স্ট্রিং হয় এবং এগুলির প্রায়শই নাম থাকে যা বড় হাতের অক্ষরের সমন্বয়ে থাকে।

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

কোনও প্রক্রিয়াতে পরিবেশের ভেরিয়েবলের সংগ্রহকে প্রায়শই "প্রক্রিয়ার পরিবেশ" হিসাবে উল্লেখ করা হয়। প্রতিটি প্রক্রিয়াটির নিজস্ব পরিবেশ রয়েছে।

পরিবেশের ভেরিয়েবলগুলি কেবল "ফরোয়ার্ড" করা যায়, অর্থাত্ একটি শিশু প্রক্রিয়া করতে পারে তার পিতামাতার প্রক্রিয়াতে পরিবেশের পরিবর্তনগুলি কখনই পরিবর্তন না এবং এটি শুরু করার পরে কোনও শিশু প্রক্রিয়ার জন্য পরিবেশ স্থাপনের পরিবর্তে, পিতামাতার প্রক্রিয়াটি কোনওটির বিদ্যমান পরিবেশ পরিবর্তন করতে পারে না শিশু প্রক্রিয়া

পরিবেশের ভেরিয়েবলগুলি env(কোনও যুক্তি ছাড়াই) তালিকাভুক্ত হতে পারে । এগুলি ছাড়াও, তারা শেল সেশনে অ-রফতানি শেল ভেরিয়েবলগুলির মতো একই প্রদর্শিত হয়। এটি শেলের জন্য কিছুটা বিশেষ কারণ অন্যান্য বেশিরভাগ প্রোগ্রামিং ভাষা সাধারণত পরিবেশের ভেরিয়েবলগুলির সাথে "সাধারণ" ভেরিয়েবলকে আন্তঃনির্মিত করে না (নীচে দেখুন)।

env বর্তমান সেশনে সেট না করে কোনও প্রক্রিয়ার পরিবেশে এক বা একাধিক এনভায়রনমেন্ট ভেরিয়েবলের মান সেট করতে ব্যবহার করা যেতে পারে:

env CC=clang CXX=clang++ make

এটি makeএনভায়রনমেন্ট ভেরিয়েবলটি CCমান clangএবং CXXসেট এ সেট করে শুরু হয় clang++

এটি প্রক্রিয়াটির জন্য পরিবেশ সাফ করার জন্যও ব্যবহৃত হতে পারে:

env -i bash

এটি শুরু হয় bashতবে বর্তমান পরিবেশটিকে নতুন bashপ্রক্রিয়াতে স্থানান্তরিত করে না ( এটির শেল ইনিশিয়ালাইজেশন স্ক্রিপ্টগুলি থেকে নতুন তৈরি করার সাথে এটির পরিবেশের পরিবর্তনশীলগুলি থাকবে )।

পার্থক্যের উদাহরণ

$ var="hello"   # create shell variable "var"
$ bash          # start _new_ bash session
$ echo "$var"   # no output
$ exit          # back to original shell session
$ echo "$var"   # "hello" is outputted
$ unset var     # remove variable

$ export VAR="hello"  # create environment variable "VAR"
$ bash
$ echo "$VAR"         # "hello" is outputted since it's exported
$ exit                # back to original shell session
$ unset VAR           # remove variable

$ ( export VAR="hello"; echo "$VAR" )  # set env. var "VAR" to "hello" in subshell and echo it
$ echo "$VAR"         # no output since a subshell has its own environment

অন্যান্য ভাষাসমূহ

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

সি, বিভিন্ন পরিবেশের ব্যবহার অ্যাক্সেস করা যেতে পারে getenv(), setenv(), putenv()এবং unsetenv()। এই রুটিনগুলির সাথে তৈরি ভেরিয়েবলগুলি সি প্রোগ্রাম শুরু হওয়া যে কোনও প্রক্রিয়া দ্বারা একইভাবে উত্তরাধিকার সূত্রে প্রাপ্ত হয়।

অন্যান্য ভাষাগুলিতে একই জিনিস সম্পাদনের জন্য বিশেষ ডেটা স্ট্রাকচার থাকতে পারে, যেমন %ENVপার্লের হ্যাশ বা ENVIRONবেশিরভাগ বাস্তবায়নে এসোসিয়েটিভ অ্যারে awk


thx, উজ্জ্বলভাবে পরিষ্কার ব্যাখ্যা। সুতরাং পরিবেশটি একটি বড় ক্ষেত্রের মতো যেখানে অন্যান্য প্রোগ্রামগুলি পরিবেশগত প্রতিটি পরিবর্তনশীল দেখতে পারে can কিছু প্রোগ্রামের ব্যক্তিগত ভেরিয়েবল রয়েছে, কেবল তারা নিজেরাই শেলগুলির মতো সেগুলি দেখতে পাবে। তবে প্রাইভেট ভেরিয়েবলগুলি তৈরি করার একটি ব্যবস্থা আছে যা "এক্সপোর্ট" নামে পরিচিত। যদি এটি ঠিকঠাকভাবে বোঝা যায় তবে কেবলমাত্র আমি যে বিষয়ে নিশ্চিত নই তা যদি একই সাথে একাধিক পরিবেশ থাকতে পারে?
শারকান্ত

@ শারকান্ত প্রতিটি চলমান প্রক্রিয়াটির নিজস্ব পরিবেশ রয়েছে। এই পরিবেশটি যে প্রক্রিয়াটি শুরু করেছিল তা থেকে উত্তরাধিকার সূত্রে প্রাপ্ত। বিভিন্ন প্রক্রিয়ার পরিবেশের মধ্যে কখনই "ক্রস টক" হয় না। কোনও প্রক্রিয়াতে পরিবেশের পরিবর্তনশীল পরিবর্তন করার একমাত্র উপায় হ'ল প্রক্রিয়া নিজেই এটি পরিবর্তন করে।
কুসালানন্দ

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

1
@ শারকান্ত বেশিরভাগ ভাষায় লাইব্রেরি ফাংশন রয়েছে যা পরিবেশের ভেরিয়েবলগুলি পেতে ও সেট করতে দেয়। সি, এই সঙ্গে সম্পন্ন করা হয় getenv(), setenv(), putenv()এবং unsetenv()। এই রুটিনগুলির সাথে তৈরি ভেরিয়েবলগুলি সি প্রোগ্রাম শুরু হওয়া যে কোনও প্রক্রিয়া দ্বারা একইভাবে উত্তরাধিকার সূত্রে প্রাপ্ত হয়। অন্যান্য ভাষায় %ENVপার্লের মতো একই জিনিসটির জন্য বিশেষ ডেটা স্ট্রাকচার থাকতে পারে ।
কুসালানন্দ

1
এফডাব্লুআইডাব্লু: exec*()ফাংশনগুলির পরিবারও প্রক্রিয়াটি সম্পাদনের জন্য পরিবেশ নির্ধারণ করতে পারে।
সাটস কাতসুরা

5

শেল ভেরিয়েবলগুলি সদৃশ করা কঠিন।

$ FOO=bar
$ FOO=zot
$ echo $FOO
zot
$ 

পরিবেশের ভেরিয়েবলগুলি অবশ্য নকল করা যায়; এগুলি কেবল একটি তালিকা এবং একটি তালিকার সদৃশ এন্ট্রি থাকতে পারে। এখানে envdup.cএটি করতে হবে।

#include <err.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

extern char **environ;

int main(int argc, char *argv[]) {
    char **newenv;
    int envcount = 0;

    if (argc < 2) errx(64, "Usage: envdup command [args ..]");

    newenv = environ;
    while (*newenv++ != NULL) envcount++;

    newenv = malloc(sizeof(char *) * (envcount + 3));
    if (newenv == NULL) err(1, "malloc failed");
    memcpy(newenv, environ, sizeof(char *) * envcount);
    newenv[envcount]   = "FOO=bar";
    newenv[envcount+1] = "FOO=zot";
    newenv[envcount+2] = NULL;

    environ = newenv;
    argv++;
    execvp(*argv, argv);
    err(1, "exec failed '%s'", *argv);
}

যা আমরা সংকলন করতে এবং বলতে চালাতে পারি envdupতারপরে envকী পরিবেশের ভেরিয়েবল সেট করা আছে তা আমাদের দেখানোর জন্য চালান ...

$ make envdup
cc     envdup.c   -o envdup
$ unset FOO
$ ./envdup env | grep FOO
FOO=bar
FOO=zot
$ 

এই সম্ভবত কত ভাল প্রোগ্রাম হ্যান্ডেল মধ্যে বাগ বা অন্যান্য oddities খোঁজার জন্য শুধুমাত্র উপকারী **environ

$ unset FOO
$ ./envdup perl -e 'exec "env"' | grep FOO
FOO=bar
$ ./envdup python3 -c 'import os;os.execvp("env",["env"])' | grep FOO
FOO=bar
FOO=zot
$ 

পাইথন 3..6 এর মতো দেখে মনে হচ্ছে অনুলিপি অনুলিপিগুলি (একটি ফাঁসী বিমূর্তি) দিয়ে গেছে যখন পার্ল 5.24 দেয় না। খোলসের কী অবস্থা?

$ ./envdup bash -c 'echo $FOO; exec env' | egrep 'bar|zot'
zot
FOO=zot
$ ./envdup zsh -c 'echo $FOO; exec env' | egrep 'bar|zot' 
bar
FOO=bar
$ 

গোশ, sudoপ্রথম পরিবেশের প্রবেশকে কেবল স্যানিটাইজ করে তবে bashদ্বিতীয়টি দিয়ে চলে তবে কি হবে ? হ্যালো PATHবা LD_RUN_PATHশোষণ আপনার sudo(এবং আরও কিছুর ?) কি সেই গর্তটির জন্য প্যাচ করা আছে ? সুরক্ষা শোষণগুলি কলিং প্রোগ্রামে "একটি অজানা পার্থক্য" বা কেবল "একটি বাগ" নয় "


1
এটি সত্য তবে একটি অজানা পার্থক্য এবং যুক্তিযুক্তভাবে প্রোগ্রামটির একটি বাগটি সদৃশ ভেরিয়েবল সেট করে।
jlliagre

1
দেখুন rt.perl.org/Public/Bug/Display.html?id=127158 (জন্য CVE-2016-2381)
Stéphane Chazelas

0

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

env –কমান্ডটি আপনাকে বর্তমানের কোনও পরিবর্তন না করে কাস্টম এনভায়রনমেন্টে অন্য প্রোগ্রাম চালানোর অনুমতি দেয়। যখন কোনও যুক্তি ছাড়াই ব্যবহার করা হয় এটি বর্তমান পরিবেশের ভেরিয়েবলগুলির একটি তালিকা মুদ্রণ করবে। printenv –কমান্ডটি সমস্ত বা নির্দিষ্ট পরিবেশের ভেরিয়েবলগুলি মুদ্রণ করে। set –কমান্ড শেল ভেরিয়েবলগুলি সেট বা আনসেট করে। যখন কোনও যুক্তি ছাড়াই ব্যবহার করা হয় এটি পরিবেশ এবং শেল ভেরিয়েবল এবং শেল ফাংশন সহ সমস্ত ভেরিয়েবলের একটি তালিকা মুদ্রণ করবে। unset –কমান্ড শেল এবং এনভায়রনমেন্ট ভেরিয়েবল মুছে ফেলে। export –কমান্ড পরিবেশের ভেরিয়েবল সেট করে

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