কমান্ড লাইনে আমি কীভাবে একটি পরিবেশের পরিবর্তনশীল সেট করব এবং এটি কমান্ডে প্রদর্শিত হবে?


151

যদি আমি দৌড়ান

export TEST=foo
echo $TEST

এটি foo আউটপুট।

যদি আমি দৌড়ান

TEST=foo echo $TEST

এটা না. এক্সপোর্ট বা স্ক্রিপ্ট ব্যবহার না করে আমি কীভাবে এই কার্যকারিতাটি পেতে পারি?


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

উত্তর:


179

এটি হ'ল শেলটি কমান্ড লাইনে পরিবর্তনশীল প্রসারণ করে এটি কমান্ডটি চালানোর আগে এবং সেই সময়ে ভেরিয়েবলটির অস্তিত্ব থাকে না। আপনি যদি ব্যবহার

TEST=foo; echo $TEST

এটা কাজ করবে।

exportপরবর্তীকালে সম্পাদিত কমান্ডের পরিবেশে ভেরিয়েবলটি প্রদর্শিত হবে (এর জন্য এটি কীভাবে কাজ করে দেখুন help export)। যদি আপনার কেবলমাত্র একটি কমান্ডের পরিবেশে পরিবর্তনশীল উপস্থিত হয় তবে আপনি যা চেষ্টা করেছেন তা ব্যবহার করুন, যেমন:

TEST=foo your-application

1
/ ইউএসআর / বিন / এনভিভির কী হবে? এটিও কাজ করে না, আপনি কেন জানেন?
বেনুবার্ড

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

@ পেটারফ যদি শেলটি কমান্ড লাইনে আসলে কমান্ড চালানোর আগে পরিবর্তনশীল প্রসারিত করে তবে কেন এটি এটিকে প্রসারিত করে না var=value sh -c 'echo "$var"'?
হ্যাক

আমি যেমন এখানে আপনাদের বুঝিয়েছি : এটি কারণ ভেরিয়েবলগুলি ডাবল কোট (যেমন, "… $var …") এর মধ্যে প্রসারিত হয় তবে একক উদ্ধৃতিতে (যেমন, '… $var …') নয়। যেহেতু echo "$var"একক উদ্ধৃতিগুলির ভিতরে রয়েছে, সেই পুরো স্ট্রিংটি sh -cবাইরের, ইন্টারেক্টিভ শেল দ্বারা ব্যাখ্যা না করেই নতুন ( ) শেলটিতে পৌঁছে যায় । … (চালিয়ে যাওয়া)
জি-ম্যান

(চালিয়ে যাওয়া)… যেমন ইগল গতকাল বলেছিল , এখানে দুটি রাউন্ড বিযুক্তকরণ রয়েছে - যদিও আমি বিশ্বাস করি যে আইগাল আপনার প্রশ্নটির ভুল ব্যাখ্যা করে। প্যারেন্ট শেল দ্বারা করা পার্সিং বাদে দুটি রাউন্ড পার্সিং নেই । পার্সিংয়ের দুটি রাউন্ড রয়েছে - একটি বহিরাগত, ইন্টারেক্টিভ (পিতামাতার) শেল দ্বারা এবং একটি নতুন ( sh -c) শিশু শেল দ্বারা।
জি-ম্যান

39

আমার সন্দেহ হয় আপনার পরিবেশের ভেরিয়েবলের পরিবর্তে শেল ভেরিয়েবলের সীমিত সুযোগ থাকতে চান । এনভায়রনমেন্ট ভেরিয়েবল হ'ল কমান্ডগুলিতে কার্যকর হওয়া স্ট্রিংগুলির একটি তালিকা ।

মধ্যে

var=value echo whatever

var=valueপ্রতিধ্বনি গ্রহণকারী পরিবেশে আপনি স্ট্রিংটি পার করছেন । তবে, echoতার পরিবেশ তালিকা এবং যে কোনও উপায়ে বেশিরভাগ শেলের মধ্যে কিছু নেই, echoঅন্তর্নির্মিত এবং তাই কার্যকর করা হয় না ।

আপনি যদি লিখতেন

var=value sh -c 'echo "$var"'

এটা অন্য বিষয় হতে পারে। এখানে, আমরা পার করছি var=valueকরার shকমান্ড, এবং shতার পরিবেশের ব্যবহার করতে ঘটবে। শেলগুলি তাদের পরিবেশ থেকে প্রাপ্ত প্রতিটি ভেরিয়েবলকে শেল ভেরিয়েবলে রূপান্তরিত করে, সুতরাং varপরিবেশে পরিবর্তনশীল shপ্রাপ্ত একটি $varভেরিয়েবলে রূপান্তরিত হবে , এবং যখন এটি echoকমান্ড লাইনে এটি প্রসারিত করবে, তখন তা হয়ে যাবে echo value। কারণ পরিবেশ ডিফল্ট উত্তরাধিকারসূত্রে হয়, echoএছাড়াও পাবেন var=valueতার পরিবেশে (অথবা হলে মৃত্যুদন্ড কার্যকর করা হয়), কিন্তু আবার, echoপরিবেশ সম্পর্কে গ্রাহ্য না করে।

এখন, যদি আমার সন্দেহ হয়, আপনি যা চান তা হ'ল শেল ভেরিয়েবলের পরিধি সীমিত করার জন্য, বেশ কয়েকটি সম্ভাব্য পন্থা রয়েছে।

বহনযোগ্যভাবে (বোর্ন এবং পসিক্স):

(var=value; echo "1: $var"); echo "2: $var"

উপরের (...) একটি সাব-শেল (বেশিরভাগ শেলের মধ্যে একটি নতুন শেল প্রক্রিয়া) শুরু করে, সুতরাং সেখানে ঘোষিত যে কোনও পরিবর্তনশীল কেবল সেই উপ-শেলকেই প্রভাবিত করবে, সুতরাং আমি উপরের কোডটি "1: মান" আউটপুট করার আশা করছিলাম এবং "2:" বা "2: যা আগে-আগে-সেট-করা ছিল" set

বেশিরভাগ বোর্নের মতো শেলসের সাহায্যে আপনি ফাংশন এবং "স্থানীয়" বিল্টিন ব্যবহার করতে পারেন:

f() {
  local var
  var=value
  echo "1: $var"
}
f
echo "2: $var"

Zsh সহ, আপনি ইনলাইন ফাংশনগুলি ব্যবহার করতে পারেন:

(){ local var=value; echo "1: $var"; }; echo "2: $var"

বা:

function { local var=value; echo "1: $var"; }; echo "2: $var"

বাশ এবং জেডএস (তবে ছাই, পিডিক্স বা এটিএন্ডটি কেএসএস নয়) সহ এই কৌশলটিও কাজ করে:

var=value eval 'echo "1: $var"'; echo "2: $var"

একটি বৈকল্পিক যে আরো কয়েকটি শেল কাজ করে ( dash, mksh, yash) কিন্তু না zsh(যদি না এর মধ্যে sh/ kshএমুলেশন):

var=value command eval 'echo "1: $var"'; echo "2: $var"

( commandপসিক্স evalশেলগুলিতে একটি বিশেষ বিল্টিনের সামনে (এখানে ) ব্যবহার করে তাদের বিশেষত্বটি মুছে ফেলা হয় (এখানে যেগুলি থেকে ভেরিয়েবল অ্যাসাইনমেন্টগুলি তারা ফিরে আসার পরে কার্যকর হয়))


আমার উদ্দেশ্যে, এটি সঠিক সমাধান। আমি চাই না যে পরিবর্তনশীল 'var' পরিবেশটিকে কলুষিত করবে যেমন এটি গৃহীত উত্তরে।
ক্রোনেনপজ

6

আপনি এটি সঠিকভাবে করছেন, তবে ব্যাশ বাক্য বাক্যটি ভুল ব্যাখ্যা করা সহজ: আপনি ভাবতে পারেন যে এনভ ভার্চ আনার echo $TESTকারণ এটি মুদ্রণ করে, এটি তা নয়। তাই দেওয়া হয়েছেechoTEST

export TEST=123

তারপর

TEST=456 echo $TEST

নিম্নলিখিত ক্রম জড়িত:

  1. শেলটি পুরো কমান্ড লাইনটিকে পার্স করে এবং সমস্ত পরিবর্তনশীল বিকল্পগুলি কার্যকর করে, সুতরাং কমান্ড লাইনটি হয়ে যায়

    TEST=456 echo 123
  2. এটি কমান্ডের আগে টেম্প ভারসেট তৈরি করে, সুতরাং এটির বর্তমান মান সংরক্ষণ করে TESTএবং এটি 456 দিয়ে ওভাররাইট করে; কমান্ড লাইন এখন

    echo 123
  3. এটি অবশিষ্ট কমান্ড কার্যকর করে, যা এই ক্ষেত্রে স্টাডাউট থেকে 123 প্রিন্ট করে (সুতরাং শেল কমান্ডটি যে টেম্পল মানটি ব্যবহার করে না TEST)

  4. এটির মান পুনরুদ্ধার করে TEST

পরিবর্তে প্রিন্টেনভ ব্যবহার করুন, কারণ এতে পরিবর্তনশীল প্রতিস্থাপন জড়িত না:

>> export TEST=123
>> printenv TEST
123
>> TEST=456 printenv TEST
456
>> printenv TEST && TEST=456 printenv TEST && TEST=789 printenv TEST && printenv TEST
123
456
789
123
>>

+1 আমি printenvধারণার প্রমাণ / পরীক্ষার পক্ষে সহায়ক (স্ক্রিপ্টের মতো আচরণ করে, এর বিপরীতে echo)
ড্যারেন

5

আপনি এটি ব্যবহার করে এই কাজটি পেতে পারেন:

TEST=foo && echo $TEST

6
এই ক্ষেত্রে, TEST=fooএকটি পৃথক বিবৃতি হিসাবে চলমান - এটি কেবলমাত্র প্রসঙ্গে সেট করা হয়নি echo
কোডফোরস্টার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.