লিনাক্স /proc/<pid>/environ
আপডেট হয় না (যেমন আমি এটি বুঝতে পারি, ফাইলটিতে প্রক্রিয়াটির প্রাথমিক পরিবেশ রয়েছে)।
আমি কিভাবে একটি প্রক্রিয়া বর্তমান পরিবেশ পড়তে পারি ?
লিনাক্স /proc/<pid>/environ
আপডেট হয় না (যেমন আমি এটি বুঝতে পারি, ফাইলটিতে প্রক্রিয়াটির প্রাথমিক পরিবেশ রয়েছে)।
আমি কিভাবে একটি প্রক্রিয়া বর্তমান পরিবেশ পড়তে পারি ?
উত্তর:
/proc/$pid/environ
প্রক্রিয়াটি তার নিজস্ব পরিবেশ পরিবর্তন করে তবে আপডেট করে। তবে অনেক প্রোগ্রাম তাদের নিজস্ব পরিবেশ পরিবর্তন করতে বিরত হন না, কারণ এটি কিছুটা অর্থহীন: একটি প্রোগ্রামের পরিবেশ সাধারণ চ্যানেলগুলির মাধ্যমে দেখা যায় না কেবলমাত্র /proc
এবং এর মাধ্যমে ps
এবং এমনকি প্রতিটি ইউনিক্স বৈকল্পের এই ধরণের বৈশিষ্ট্য নেই, তাই অ্যাপ্লিকেশনগুলি নির্ভর করে না চালু কর.
কার্নেলের সাথে সম্পর্কিত হিসাবে, পরিবেশটি কেবলমাত্র execve
সিস্টেম কলের আর্গুমেন্ট হিসাবে উপস্থিত হয় যা প্রোগ্রাম শুরু করে। লিনাক্স মেমোরির একটি অঞ্চল উন্মুক্ত করে /proc
এবং কিছু প্রোগ্রাম এই অঞ্চলটিকে আপডেট করে অন্যরা না করে। বিশেষত, আমি মনে করি না কোনও শেল এই অঞ্চলটিকে আপডেট করে। অঞ্চলটির একটি নির্দিষ্ট আকার রয়েছে বলে নতুন ভেরিয়েবল যুক্ত করা বা কোনও মানের দৈর্ঘ্য পরিবর্তন করা অসম্ভব।
PATH=foo
শেলটিতে লেখার অর্থ এই নয় যে শেলটি পরিবর্তন হতে চলেছে *envp
। কিছু শেলগুলিতে, এটি কেবলমাত্র একটি অভ্যন্তরীণ ডেটা কাঠামো আপডেট করেছে এবং এটি বাহ্যিক প্রোগ্রামের সম্পাদন কোড যা আপডেট করে *envp
। এ assign_in_env
মধ্যে variables.c
ব্যাশ সোর্সে, উদাহরণস্বরূপ।
fork
তবে libc sys_fork
শিশু প্রক্রিয়াটির জন্য হ্যাপ বরাদ্দ পরিবেশ ব্যবহার করে কল করে।
argv
আরও সাধারণ তবে উভয় বিদ্যমান)।
আপনি কোনও প্রক্রিয়াটির প্রাথমিক পরিবেশটি পড়তে পারেন /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
আমার জন্য এটি সমাধান।
প্রক্রিয়াটি যখন তার পরিবেশের ভেরিয়েবলগুলি অর্জন করে / মুছে দেয় তখন এটি আপডেট হয়। আপনার কাছে এমন একটি রেফারেন্স রয়েছে যা জানায় যে 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 ~]$
export foo=bar
এক ব্যাশের অধিবেশন (পিড এক্সএক্সএক্সএক্সএক্সএক্সএক্স) করি, তারপরে cat /proc/xxxx/environ | tr \\0 \\n
অন্যান্য বাশের অধিবেশন করুন এবং আমি দেখতে পাচ্ছি না foo
।
gdb
, তবে এখনও সেখানে কোনও উল্লেখ নেই। মেমরির পরিবেশের পরিবর্তনশীল ব্লকগুলি যখনই পরিবর্তন হয় এবং পুনরায় প্রসেস ফাইল সিস্টেমে তার নিজস্ব প্রক্রিয়া 'এনভায়রন ফাইলে প্রতিফলিত হয় না, তবে শিশু প্রক্রিয়া দ্বারা উত্তরাধিকার সূত্রে অনুমতি দেয়। এর অর্থ এটি যখন কাঁটাচামচ ঘটে তখন অভ্যন্তরীণ বিবরণগুলি জানার পক্ষে আরও সহজ হতে পারে, কীভাবে শিশু প্রক্রিয়াটি পরিবেশের ভেরিয়েবলগুলি অনুলিপি করা হয় gets
ঠিক আছে নিম্নলিখিতটি লেখকের আসল উদ্দেশ্যগুলির সাথে সম্পর্কিত নয় তবে আপনি যদি সত্যিই "পড়ুন" করতে চান তবে আপনি /proc/<pid>/environ
চেষ্টা করতে পারেন
strings /proc/<pid>/environ
যা এর চেয়ে ভাল cat
।
strings
। সহজবোধ্য রাখো.
xargs --null
।
tr '\0' '\n' < /proc/$$/environ | ...