এনভির আউটপুটে আমি দেখতে পাচ্ছি এমন একটি পরিবর্তনশীল কেন মুদ্রণ করতে পারি না?


9

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

আমি দুটি শেল এ এবং বি (পিআইডি 420) তৈরি করেছি, উভয়ই চলছে zsh। শেল থেকে এআই নিম্নলিখিত চালিত।

sudo gdb -p 420
(gdb) call setenv("FOO", "bar", 1)
(gdb) detach

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

এটি আমার নিজস্ব আর্চ জিএনইউ / লিনাক্স সিস্টেম এবং একটি উবুন্টু ভিএম উভয়ে পরীক্ষা করা হয়েছিল। আমি এটি পরীক্ষা করেছিলাম bashযেখানে পরিবর্তনশীল এমনকি এনভির মধ্যেও দেখা যায় নি। এটি যদিও আমার জন্য হতাশাব্যঞ্জক, যদি শেলটি তার পরিবেশের অনুলিপি সময়ে একটি অনুলিপিটি ক্যাশে করে এবং কেবলমাত্র এটি ব্যবহার করে (যা কোনও লিঙ্কযুক্ত প্রশ্নের মধ্যে পরামর্শ দেওয়া হয়েছিল) তা বোঝায়। zshচলকটি কেন দেখতে পারে তা এখনও উত্তর দেয় না ।

echo $FOOখালি আউটপুট কেন ?


সম্পাদনা

মন্তব্যে ইনপুট দেওয়ার পরে আমি আরও কিছু পরীক্ষা করার সিদ্ধান্ত নিয়েছি। ফলাফলগুলি নীচের সারণিতে দেখা যায়। প্রথম কলামে শেলটি যা FOOভেরিয়েবলটি ইনজেক্ট করা হয়েছিল। প্রথম সারিতে কমান্ডটি রয়েছে যার আউটপুট এটির নীচে দেখা যায়। পরিবর্তনশীল FOOব্যবহার ইনজেকশনের ছিল: sudo gdb -p 420 -batch -ex 'call setenv("FOO", "bar", 1)'। Zsh সম্পর্কিত নির্দিষ্ট কমান্ডগুলি zsh -c '...'ব্যাশ ব্যবহার করেও পরীক্ষা করা হয়েছিল। ফলাফলগুলি অভিন্ন ছিল, তাদের আউটপুট বংশবৃদ্ধির জন্য বাদ দেওয়া হয়েছিল।

আর্চ জিএনইউ / লিনাক্স, জেডএস 5.3.1, বাশ 4.4.12 (1)

|      |  env | grep FOO  | echo $FOO |  zsh -c 'env | grep FOO'  |  zsh -c 'echo $FOO'  |         After export FOO          |
|------|------------------|-----------|---------------------------|----------------------|-----------------------------------|
| zsh  |  FOO=bar         |           | FOO=bar                   | bar                  | No Change                         |
| bash |                  | bar       |                           |                      | Value of FOO visible in all tests |

উবুন্টু 16.04.2 এলটিএস, জেডএস 5.1.1, বাশ 4.3.48 (1)

|      |  env | grep FOO  | echo $FOO |  zsh -c 'env | grep FOO'  |  zsh -c 'echo $FOO'  |         After export FOO          |
|------|------------------|-----------|---------------------------|----------------------|-----------------------------------|
| zsh  |  FOO=bar         |           | FOO=bar                   | bar                  | No Change                         |
| bash |                  | bar       |                           |                      | Value of FOO visible in all tests |

উপরেরগুলি দ্বারা বোঝা যাচ্ছে যে ফলাফলগুলি বিতরণ অজ্ঞেয়। এটি আমার অনেক বেশি বলুন না zshএবং bashভিন্নভাবে ভেরিয়েবল হ্যান্ডেলে সেটিং। তদতিরিক্ত, export FOOশেলের উপর নির্ভর করে এই প্রসঙ্গে খুব আলাদা আচরণ রয়েছে। আশা করি এই পরীক্ষাগুলি অন্য কারও কাছে কিছু পরিষ্কার করে দিতে পারে।


এর zsh -c 'echo $FOO'পরিবর্তে আপনি যদি (একক উদ্ধৃতি ব্যবহার করুন!) করেন তবে কী হবে? আপনি কি এটি দেখতে পারেন?
ব্যবহারকারী 1934428

সঠিক মানটি একটি নতুন সাব শেল থেকে মুদ্রিত হয়েছে (বাশ সন্তানের জন্যও পরীক্ষিত)। স্পষ্টতই পরিবেশটি একরকম অবিচল রয়েছে যেহেতু শিশু এটির উত্তরাধিকারী হতে পারে তবে পিতামাতা কেন এটি সম্মান করে না?
আরএলএফ

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

2
আমি উবুন্টু ১.0.০৪ তে zsh 5.1.1 এবং ব্যাশ 4.3.48 (1) দিয়ে পরীক্ষা করেছি এবং মনে হচ্ছে জিডিবিতে পরিবেশের পরিবর্তনশীল সেট করা zshএটি শেল ভেরিয়েবল হিসাবে দৃশ্যমান করে না তবে এটি শিশু প্রক্রিয়াগুলিতে প্রেরণ করে দেয় (যেমন আপনি) পরিলক্ষিত হয়েছে, এক করার সময় bash নেই এটি একটি শেল পরিবর্তনশীল যেমন দৃশ্যমান করতে কিন্তু আছে না এটা চাইল্ড প্রসেস কাছে হস্তান্তর কারণ হোন! দেখে মনে হচ্ছে zsh এবং ব্যাশগুলি ভেরিয়েবলগুলি পরিচালনা করার জন্য বিভিন্ন কৌশল ব্যবহার করে, zsh ট্র্যাকিং নন-এনভায়রনমেন্ট ভেরিয়েবল এবং বাশ তার পরিবেশের সমস্ত কিছু সংরক্ষণ করে যা এটি কোনও (সাব -হেল) শিশু প্রবর্তনের সময় স্যানিটাইজ করে।
এলিয়াহ কাগন

এলিয়াকাগান, আকর্ষণীয়; আপনার উত্তর হিসাবে পোস্ট করা উচিত। আমিও ভাবছি যদি আপনি চালিত export FOOহন তবে এটি কোনও পার্থক্য রাখে bash?
ওয়াইল্ডকার্ড

উত্তর:


2

বেশিরভাগ শেলগুলি getenv()/ setenv()/ putenv()API ব্যবহার করে না ।

শুরু করার পরে, তারা প্রতিটি পরিবেশের ভেরিয়েবলের জন্য শেল ভেরিয়েবল তৈরি করে। এগুলি অভ্যন্তরীণ কাঠামোগুলিতে সংরক্ষণ করা হবে যা ভেরিয়েবলটি রফতানি হয়েছে কিনা, যেমন কেবল অন্যান্য পঠন যেমন অন্য তথ্য বহন করা প্রয়োজন ... তারা এর environজন্য libc ব্যবহার করতে পারবেন না ।

একইভাবে, এবং সেই জন্য তারা ব্যবহার করবে না execlp(), execvp()কমান্ডগুলো কিন্তু কল করার execve()সিস্টেম কল সরাসরি কম্পিউটিং envp[]তাদের রপ্তানি ভেরিয়েবল তালিকার উপর ভিত্তি অ্যারে।

সুতরাং আপনার মধ্যে gdb, আপনাকে সেই শেলগুলি ভেরিয়েবলের অভ্যন্তরীণ সারণিতে একটি এন্ট্রি যুক্ত করতে হবে, বা সম্ভবত সঠিক ফাংশনটি কল করতে হবে যা এটি export VAR=valueনিজের দ্বারা সেই টেবিলটি আপডেট করার জন্য কোনও কোড ব্যাখ্যা করে।

আপনি কেন কল করার সময় bashএবং কেন আপনি zshকল setenv()করেন তার মধ্যে তফাত দেখা যায় gdb, আমার সন্দেহ হয় কারণ আপনি setenv()শেলটি শুরু করার আগে কল করছেন , উদাহরণস্বরূপ প্রবেশ করার পরে main()

আপনি লক্ষ্য করবেন bash'র main()হয় int main(int argc, char* argv[], char* envp[])(এবং bashমানচিত্র ভেরিয়েবল থেকে যারা env মধ্যে Vars envp[]) যখন zsh' s হয় int main(int argc, char* argv[])এবং zshথেকে ভেরিয়েবল পায় environপরিবর্তে। setenv()সংশোধন করে environতবে envp[]স্থান পরিবর্তন করতে পারে না (কেবলমাত্র কয়েকটি সিস্টেমে পঠনযোগ্য পাশাপাশি সেই পয়েন্টারগুলিতে নির্দেশিত স্ট্রিংগুলি)।

environযাইহোক, শেল শুরুর পরে পড়ার পরে, ব্যবহার setenv()অকার্যকর হবে কারণ শেলটি আর ব্যবহার করে না environ(বা getenv()) পরে।

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