কোনও প্রক্রিয়ার পরিবেশ পরিবর্তনশীল কীভাবে পড়বেন


43

লিনাক্স /proc/<pid>/environআপডেট হয় না (যেমন আমি এটি বুঝতে পারি, ফাইলটিতে প্রক্রিয়াটির প্রাথমিক পরিবেশ রয়েছে)।

আমি কিভাবে একটি প্রক্রিয়া বর্তমান পরিবেশ পড়তে পারি ?

উত্তর:


20

/proc/$pid/environপ্রক্রিয়াটি তার নিজস্ব পরিবেশ পরিবর্তন করে তবে আপডেট করে। তবে অনেক প্রোগ্রাম তাদের নিজস্ব পরিবেশ পরিবর্তন করতে বিরত হন না, কারণ এটি কিছুটা অর্থহীন: একটি প্রোগ্রামের পরিবেশ সাধারণ চ্যানেলগুলির মাধ্যমে দেখা যায় না কেবলমাত্র /procএবং এর মাধ্যমে psএবং এমনকি প্রতিটি ইউনিক্স বৈকল্পের এই ধরণের বৈশিষ্ট্য নেই, তাই অ্যাপ্লিকেশনগুলি নির্ভর করে না চালু কর.

কার্নেলের সাথে সম্পর্কিত হিসাবে, পরিবেশটি কেবলমাত্র execveসিস্টেম কলের আর্গুমেন্ট হিসাবে উপস্থিত হয় যা প্রোগ্রাম শুরু করে। লিনাক্স মেমোরির একটি অঞ্চল উন্মুক্ত করে /procএবং কিছু প্রোগ্রাম এই অঞ্চলটিকে আপডেট করে অন্যরা না করে। বিশেষত, আমি মনে করি না কোনও শেল এই অঞ্চলটিকে আপডেট করে। অঞ্চলটির একটি নির্দিষ্ট আকার রয়েছে বলে নতুন ভেরিয়েবল যুক্ত করা বা কোনও মানের দৈর্ঘ্য পরিবর্তন করা অসম্ভব।


সুতরাং, কার্যকরভাবে প্রক্রিয়া '* envp (পরিবেশের সেটিংসে পয়েন্টারগুলির অ্যারে) অ্যাক্সেস করার কোনও উপায় নেই। @ গিলস, আপনি কি দয়া করে দেখাতে পারেন যে ডিবাগারটি সংযুক্ত করা এবং পরিবেশের সেটিংসে পয়েন্টারগুলির অ্যারে পড়া সম্ভব কিনা।
নিখিল মুলি 15'12

2
@ নিখিল শিওর, এটি। তবে কেবল আপনি PATH=fooশেলটিতে লেখার অর্থ এই নয় যে শেলটি পরিবর্তন হতে চলেছে *envp। কিছু শেলগুলিতে, এটি কেবলমাত্র একটি অভ্যন্তরীণ ডেটা কাঠামো আপডেট করেছে এবং এটি বাহ্যিক প্রোগ্রামের সম্পাদন কোড যা আপডেট করে *envp। এ assign_in_envমধ্যে variables.cব্যাশ সোর্সে, উদাহরণস্বরূপ।
গিলস 'তাই খারাপ হওয়া বন্ধ করুন'

9
@ গিলস: এই উত্তরটি সবচেয়ে ভাল বিভ্রান্তিকর (-1)। / Proc / $$ / পরিবেশে পরিবেশ প্রক্রিয়াটির স্ট্যাক থেকে পড়ে। Fs / proc / base.c দেখুন। এটি প্রাথমিক পরিবেশ। এটি কখনই আপডেট হয় না এবং বাস্তবে তা হতে পারে না। Libc setenv যে পরিবেশটি ব্যবহার করে তা স্তূপে বরাদ্দ করা হয় এবং স্ট্যাকের পরিবেশের বিষয়বস্তু দিয়ে সূচনা করা হয়। যদি প্রক্রিয়াটি libc- কে কল করে forkতবে libc sys_forkশিশু প্রক্রিয়াটির জন্য হ্যাপ বরাদ্দ পরিবেশ ব্যবহার করে কল করে।
জোনাথন বেন-অভ্রাহাম

7
@ জোনাথনবেন-অভ্রাহাম আপনি ঠিক বলেছেন যে কোনও পরিবেশে প্রাথমিক পরিবেশ আপডেট হয়নি। তবে area অঞ্চলটি কেবল লিনাক্সের অধীনেই পঠিত হয় না, আমি এমন প্রোগ্রামগুলির মুখোমুখি হয়েছি যা তাদের অবস্থানের প্রতিবেদন করতে এটি ব্যবহার করে (স্ট্যাটাস রিপোর্টগুলি argvআরও সাধারণ তবে উভয় বিদ্যমান)।
গিলস 21'23 এ 'খারাপ হওয়া বন্ধ করুন'

39

আপনি কোনও প্রক্রিয়াটির প্রাথমিক পরিবেশটি পড়তে পারেন /proc/<pid>/environ

যদি কোনও প্রক্রিয়া তার পরিবেশ পরিবর্তন করে, তবে পরিবেশটি পড়তে আপনার অবশ্যই প্রক্রিয়াটির জন্য প্রতীক টেবিল থাকতে হবে এবং বিশ্বব্যাপী ভেরিয়েবল থেকে পরিবেশটি পড়তে ptraceসিস্টেম কল (উদাহরণস্বরূপ ব্যবহার করে gdb) ব্যবহার করতে হবে char **__environ। চলমান লিনাক্স প্রক্রিয়া থেকে কোনও ভেরিয়েবলের মান পাওয়ার অন্য কোনও উপায় নেই।

এটাই উত্তর। এখন কিছু নোটের জন্য।

উপরেরটি ধরে নিয়েছে যে প্রক্রিয়াটি পসিক্স অনুবর্তী, মানে রেফ স্পেসেchar **__environ উল্লিখিত একটি বৈশ্বিক পরিবর্তনশীল ব্যবহার করে প্রক্রিয়াটি তার পরিবেশ পরিচালনা করে ।

প্রক্রিয়াটির প্রাথমিক পরিবেশ প্রক্রিয়াটির স্ট্যাকের একটি নির্দিষ্ট দৈর্ঘ্যের বাফারে প্রক্রিয়ায় স্থানান্তরিত হয়। (এটি করার মতো সাধারণ প্রক্রিয়াটি linux//fs/exec.c:do_execve_common(...))) যেহেতু বাফারের আকার প্রাথমিক পরিবেশের জন্য প্রয়োজনীয় আকারের চেয়ে বেশি গণনা করা হয়, আপনি বিদ্যমান ভেরিয়েবলগুলি মোছা বা স্ট্যাকটি ভেঙে ফেলা ছাড়া নতুন ভেরিয়েবল যুক্ত করতে পারবেন না। সুতরাং, কোনও প্রক্রিয়ার পরিবেশের পরিবর্তনের অনুমতি দেওয়ার জন্য কোনও যুক্তিসঙ্গত স্কিম হিপ ব্যবহার করবে, যেখানে স্বেচ্ছাসেবী আকারে মেমরি বরাদ্দ এবং মুক্ত করা যেতে পারে, যা জিএনইউ libc( glibc) আপনার জন্য ঠিক তাই করে।

প্রক্রিয়াটি যদি ব্যবহার করে glibc, তবে এটি পসিক্স অনুগত, গ্লিবসি-তে __environঘোষিত হওয়ার সাথে সাথে glibc//posix/environ.cমেমরিটির __environএকটি পয়েন্টার দিয়ে mallocএটি প্রসেসের গাদা থেকে শুরু করে, তারপরে স্ট্যাক থেকে প্রাথমিক পরিবেশটিকে এই স্তূপ অঞ্চলে অনুলিপি করে। প্রতিটি সময় প্রক্রিয়াটি setenvফাংশনটি ব্যবহার করে , সেই জায়গার আকারটি সামঞ্জস্য করতে glibcএকটি reallocকরে __environযা নতুন মান বা পরিবর্তনশীলকে সমন্বিত করতে নির্দেশ করে। (আপনি গ্লিবিসি উত্স কোডটি এর সাথে ডাউনলোড করতে পারেন git clone git://sourceware.org/git/glibc.git glibc)। সত্যিকারের প্রক্রিয়াটি বুঝতে আপনাকে hurd//init/init.c:frob_kernel_process()হার্ট কোডটিও পড়তে হবে (গিট ক্লোন গিট: //git.sv.gnu.org/hurd/hurb.git hurb)।

এখন যদি নতুন প্রক্রিয়াটি কেবলমাত্র স্ট্যাকের forkউপরের execওভাররাইটিং ছাড়াই সম্পাদিত হয়, তবে আর্গুমেন্ট এবং পরিবেশের অনুলিপি করা যাদুটি সম্পন্ন হয় linux//kernel/fork.c:do_fork(...), যেখানে copy_processরুটিন কলগুলি dup_task_structনতুন প্রসেসের স্ট্যাক কল করে কল করে alloc_thread_info_node, যা নতুন প্রক্রিয়াটি ব্যবহার করার জন্য কল করে setup_thread_stack( linux//include/linux/sched.h) alloc_thread_info_node

পরিশেষে, পসিক্স __environকনভেনশনটি একটি ব্যবহারকারী-স্থান কনভেনশন। লিনাক্স কার্নেলের কোনও কিছুর সাথে এর কোনও সংযোগ নেই। আপনি বিশ্বব্যাপী ব্যবহার না করে glibcএবং ব্যবহার ছাড়াই একটি ইউজারস্পেস প্রোগ্রাম লিখতে পারেন __environএবং তারপরে আপনার পছন্দমতো পরিবেশের ভেরিয়েবলগুলি পরিচালনা করতে পারেন। এটি করার জন্য আপনাকে কেউ গ্রেপ্তার করবে না তবে আপনাকে নিজের পরিবেশ ব্যবস্থাপনার কাজগুলি ( setenv/ getenv) এবং আপনার নিজের র‌্যাপারের জন্য লিখতে হবে sys_execএবং সম্ভবত আপনি আপনার পরিবেশের পরিবর্তনগুলি কোথায় রেখেছেন তা কেউ অনুমান করতে সক্ষম হবে না।


ফাইলগুলির মধ্যে অনেকের /proc/[pid]/কাছে একটি অদ্ভুত এনকোডিং রয়েছে বলে মনে হয় (অন্য কেউ কী এবং কেন জানেন। আমার জন্য, সহজেই cat environপরিবেশের পরিবর্তনশীলগুলি পড়ার জন্য খুব শক্ত বিন্যাসে মুদ্রণ করবে। cat environ | stringsআমার জন্য এটি সমাধান।
retrohacker

@ রেট্রোহ্যাকার এটি আরও দৃ
ফ্রাঙ্ক

20

প্রক্রিয়াটি যখন তার পরিবেশের ভেরিয়েবলগুলি অর্জন করে / মুছে দেয় তখন এটি আপডেট হয়। আপনার কাছে এমন একটি রেফারেন্স রয়েছে যা জানায় যে environফাইলটি / প্রোক্রোম ফাইল সিস্টেমের অধীনে তার প্রক্রিয়া ডিরেক্টরিতে প্রক্রিয়াটির জন্য ফাইল আপডেট হয় না?

xargs --null --max-args=1 echo < /proc/self/environ

অথবা

xargs --null --max-args=1 echo < /proc/<pid>/environ

অথবা

ps e -p <pid>

উপরের প্রক্রিয়াটির পরিবেশগত ভেরিয়েবলগুলি psআউটপুট বিন্যাসে মুদ্রণ করবে , পাঠ্য-প্রক্রিয়াকরণ (পার্সিং / ফিল্টারিং) পরিবেশের ভেরিয়েবলগুলি তালিকা হিসাবে দেখতে প্রয়োজনীয়।

সোলারিস (জিজ্ঞাসা করা হয়নি, তবে রেফারেন্সের জন্য আমি এখানে পোস্ট করব):

/usr/ucb/ps -wwwe <pid>

অথবা

pargs -e <pid> 

সম্পাদনা: / proc / pid / পরিবেশ আপডেট করা হয়নি! আমি সংশোধন করেছি. যাচাই প্রক্রিয়া নীচে। যাইহোক, যেসব শিশুদের থেকে প্রক্রিয়াটি কাঁটাচামচ করা হয় তাদের প্রক্রিয়া পরিবেশের পরিবর্তনশীল হয় এবং এটি তাদের নিজ নিজ / প্রকৃত / স্ব / পরিবেশের ফাইলে দৃশ্যমান। (স্ট্রিং ব্যবহার করুন)

শেলের সাথে: এখানে xargs একটি শিশু প্রক্রিয়া এবং তাই পরিবেশের পরিবর্তনশীল উত্তরাধিকার সূত্রে প্রাপ্ত হয় এবং এটির /proc/self/environফাইলটিতেও প্রতিফলিত হয় ।

[centos@centos t]$ printenv  | grep MASK
[centos@centos t]$ export MASK=NIKHIL
[centos@centos t]$ printenv  | grep MASK
MASK=NIKHIL
[centos@centos t]$ xargs --null --max-args=1 echo < /proc/self/environ  | grep MASK
MASK=NIKHIL
[centos@centos t]$ unset MASK
[centos@centos t]$ printenv  | grep MASK
[centos@centos t]$ xargs --null --max-args=1 echo < /proc/self/environ  | grep MASK
[centos@centos t]$

এটি অন্য সেশন থেকে পরীক্ষা করা হচ্ছে, যেখানে টার্মিনাল / সেশনটি শেলটির চাইল্ড প্রক্রিয়া নয় যেখানে পরিবেশ পরিবর্তনশীল সেট করা আছে।

একই হোস্টে অন্য টার্মিনাল / সেশন থেকে যাচাই করা হচ্ছে:

টার্মিনাল 1 : নোট করুন যে প্রিন্টেনভটি কাঁটাচামচ এবং এটি ব্যাশের একটি শিশু প্রক্রিয়া এবং তাই এটি তার নিজস্ব এনভায়রনমেন্ট ফাইলটি পড়ে।

[centos@centos t]$ echo $$
2610
[centos@centos t]$ export SPIDEY=NIKHIL
[centos@centos t]$ printenv | grep SPIDEY
SPIDEY=NIKHIL
[centos@centos t]$ 

টার্মিনাল 2: একই হোস্টে - উপরের ভেরিয়েবলটি সেট করা একই শেলের সাথে এটি চালু করবেন না, টার্মিনালটি পৃথকভাবে চালু করুন।

[centos@centos ~]$ echo $$
4436
[centos@centos ~]$ xargs --null --max-args=1 echo < /proc/self/environ | grep -i spidey
[centos@centos ~]$ strings -f /proc/2610/environ | grep -i spidey
[centos@centos ~]$ xargs --null --max-args=1 echo < /proc/2610/environ | grep -i spidey
[centos@centos ~]$ 

1
আমি export foo=barএক ব্যাশের অধিবেশন (পিড এক্সএক্সএক্সএক্সএক্সএক্সএক্স) করি, তারপরে cat /proc/xxxx/environ | tr \\0 \\nঅন্যান্য বাশের অধিবেশন করুন এবং আমি দেখতে পাচ্ছি না foo

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

আপনি সঠিক. আমি সংশোধন করেছি. ধন্যবাদ। ব্যবহারকারী প্রসেস গ্রুপের সাথে আলাদা প্রক্রিয়ার পরিবেশগত ভেরিয়েবলগুলি পরীক্ষা করতে আমাকে এখন আমার ম্যানুয়ালগুলি পড়তে হবে।
নিখিল মুলি

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

আমি আশা করি @ গিলস তার উপর কিছু টর্চ লাইট নিক্ষেপ করবে .. :-)
নিখিল মুলি

7

ঠিক আছে নিম্নলিখিতটি লেখকের আসল উদ্দেশ্যগুলির সাথে সম্পর্কিত নয় তবে আপনি যদি সত্যিই "পড়ুন" করতে চান তবে আপনি /proc/<pid>/environচেষ্টা করতে পারেন

strings /proc/<pid>/environ

যা এর চেয়ে ভাল cat


1
জন্য +1 strings। সহজবোধ্য রাখো.
এড র্যান্ডাল

@ এডরানডাল সম্মত হন, এটি বনামের চেয়ে সহজ পদ্ধতির মত মনে হয় xargs --null
প্রতি লন্ডবার্গ

"ফাইল" নাল বাতিল করা হয়েছে, নতুন-লাইন দিয়ে নালগুলি প্রতিস্থাপন করুন এবং সাধারণ সরঞ্জামগুলি আবার কাজ করে (সাধারণ ক্যাভ্যাটস সহ), যেমন:tr '\0' '\n' < /proc/$$/environ | ...
থোর
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.