কেন en র্যান্ডোমকে 'এনভির' আউটপুটটিতে অন্তর্ভুক্ত করা হচ্ছে না?


23

আমি জানি envএকটি শেল কমান্ড, এটি বর্তমান পরিবেশের ভেরিয়েবলগুলির একটি তালিকা মুদ্রণ করতে ব্যবহৃত হতে পারে। এবং যতদূর আমি বুঝতে পারি, RANDOMএটি পরিবেশের পরিবর্তনশীলও।

সুতরাং কেন, যখন আমি envলিনাক্স চালু করি , আউটপুটটি অন্তর্ভুক্ত হয় না RANDOM?


4
envএটি শেল কমান্ড নয় কারণ এটি সাধারণত শেলের মধ্যে নির্মিত হয় না।
স্কুলেলি

বাশের জন্য প্রশংসিত বিটিডাব্লু, declare -xশেল বিল্টিনের সমতুল্য।
wjandrea

উত্তর:


42

RANDOMপরিবেশের পরিবর্তনশীল নয়। এটি কয়েকটি শাঁস দ্বারা পরিচালিত একটি শেল ভেরিয়েবল। এটি সাধারণত ডিফল্টরূপে রফতানি হয় না। এ কারণেই এটি এর আউটপুটে প্রদর্শিত হবে না env

একবার এটি একবার অন্তত ব্যবহার করা হয়েছে, এটা হবে আউটপুট দেখা set, যা, নিজে, তালিকা শেল ভেরিয়েবল (এবং ফাংশন) এবং তাদের মান বর্তমান শেল সেশনে। এই আচরণটি শেলের উপর নির্ভর করে এবং pdkshওপেনবিএসডি ব্যবহার করে, পূর্বে ব্যবহৃত না হলেও RANDOMতালিকাভুক্ত হবে set


এই উত্তরটির বাকী অংশটি RANDOMরফতানি করা হলে (যেমন পরিবেশের পরিবর্তনশীলে রূপান্তরিত) হয়ে গেলে কী ঘটবে বলে আশা করা যায় concerns

এর সাথে রফতানি করা এটিকে export RANDOMপরিবেশের পরিবর্তনযোগ্য করে তুলবে তবে এর ব্যবহার মারাত্মকভাবে সীমাবদ্ধ থাকবে কারণ একটি শিশু প্রক্রিয়াতে এর মান হবে "এলোমেলো তবে স্থির" (যার অর্থ এটি অপরিবর্তনীয় এলোমেলো সংখ্যা হবে)। সঠিক আচরণ শাঁসের মধ্যে পার্থক্য করে।

আমি pdkshনীচের উদাহরণে ওপেনবিএসডি ব্যবহার করছি এবং আমি প্রতিটি awkরানে একটি নতুন এলোমেলো মান পাই (তবে একই সংস্করণের মধ্যে প্রতিবার একই মান awk)। ব্যবহার করে bash, আমি সমস্ত অনুরোধে ঠিক একই র্যান্ডম মান পেতে চাই awk

$ awk 'BEGIN { print ENVIRON["RANDOM"], ENVIRON["RANDOM"] }'
25444 25444

$ awk 'BEGIN { print ENVIRON["RANDOM"], ENVIRON["RANDOM"] }'
30906 30906

ইন bash, রফতানির মানটি শেলটিতে RANDOMব্যবহার ছাড়াই স্থির থাকবে RANDOM(যেখানে প্রতিটি ব্যবহার $RANDOMএখনও একটি নতুন মান দেয়)।

এর কারণ হল প্রতিটি রেফারেন্স শেল পরিবর্তনশীল RANDOM মধ্যে bashশেল ব্যবহারের অভ্যন্তরীণ তোলে get_random()পরিবর্তনশীল একটি নতুন র্যান্ডম মান দিতে ফাংশন, কিন্তু শেল আপডেট করা হয় না এনভায়রনমেন্ট ভেরিয়েবল RANDOM । এর ফলে অন্য গতিশীল মত আচরণের অনুরূপ bashযেমন ভেরিয়েবল, LINENO, SECONDS, BASHPIDইত্যাদি

এনভায়রনমেন্ট ভেরিয়েবল আপডেট করতে RANDOMমধ্যে bash, আপনি এটি শেল ভেরিয়েবলের মান নির্ধারণ করতে হবে RANDOM এবং পুনরায় রপ্তানি এটা:

export RANDOM="$RANDOM"

এটি আমার কাছে অস্পষ্ট যে এটির এলোমেলো নম্বর জেনারেটরে পুনরায় বীজ দেওয়ার অতিরিক্ত পার্শ্ব প্রতিক্রিয়া আছে bashকি না (তবে একটি শিক্ষিত অনুমান এটি হ'ল না)।


1
না RANDOMআগে আপনি এটা ব্যবহার এমনকি একটি মূল্য আছে? আমি সবসময় ধরে নিয়েছিলাম এটি কেবলমাত্র ডাকা হলেই জনবহুল।
টেরডন

1
এটি নয়, বাশ ম্যানুয়ালটিতে এটি উল্লেখ করা হয়েছে।
টেরডন

1
যদিও আপনি এমনকি যদি করেন export RANDOMবা declare -p RANDOMএটি প্রদর্শিত হয় তবে আমি নিশ্চিত নই যে এটির কোনও ব্যবহারের রেফারেন্স দেওয়ার আগে এটির অস্তিত্ব নেই
কিনা

1
"শিশু প্রক্রিয়াতে এর মান এলোমেলো হলেও স্থির থাকবে।" যদি এটি স্থির হয় তবে এটি এলোমেলো নয় , এটি তিন বাইট বা ষোল হোক।
l0b0

3
@ l0b0 এটি এলোমেলোভাবে হবে যে আপনি এটি অনুমান করতে পারবেন না। স্পষ্টতই, আপনি একবার এটি পড়ার পরে, এটি আর এলোমেলো নয় যেহেতু এটি পরিবর্তন হবে না (যতক্ষণ না আমি দেখিয়েছি পুনরায় রফতানি করা না হলে, পরিবেশের পরিবর্তনশীল একটি নতুন এলোমেলো মান পাবে)। এ কারণেই আমি বলেছিলাম এটি এলোমেলো তবে স্থির। আমি এখন কিছুটা লেখায় এটি স্পষ্ট করে দিয়েছি।
কুসালানন্দ

16

আপনার শেল সেশনে সেট করা সমস্ত ভেরিয়েবলগুলি পরিবেশের ভেরিয়েবল নয়। "পরিবেশ পরিবর্তনশীল" বলতে কেবল সেই পরিবর্তনশীলগুলিকে বোঝায় যা exportবিল্টিন ব্যবহার করে পরিবেশে রফতানি করা হয়েছিল । envকমান্ড শুধুমাত্র যেমন ছাপে পরিবেশ ভেরিয়েবল। উদাহরণ স্বরূপ:

$ foo="bar"
$ env | grep foo ## returns nothing
$ export foo
$ env | grep foo ## now, env will print it
foo=bar

আপনি যদি আপনার সেশনে সেট করা সমস্ত ভেরিয়েবলগুলি দেখতে চান তবে সেগুলি রফতানি করা হয়েছে তা নির্বিশেষে, আপনি ব্যবহার করতে পারেন set:

$ set | grep foo=
foo=bar

setBuiltin এছাড়াও ফাংশন ফেরৎ, তাই শুধুমাত্র ভেরিয়েবল দেখতে, আপনি ব্যবহার করতে পারেন:

set | grep  '^[^[:space:]]*='

অবশেষে, RANDOMভেরিয়েবলটি বিশেষ যে এটি কেবলমাত্র একটি মান নির্ধারিত হয় যখন আপনি এটি উল্লেখ করেন। এটি বাশ (1) এ উল্লেখ করা হয়েছে :

RANDOM

    প্রতিবার এই প্যারামিটারটি উল্লেখ করা হয়, 0 এবং 32767 এর মধ্যে একটি এলোমেলো পূর্ণসংখ্যার উত্পন্ন হয়। এলোমেলো সংখ্যার ক্রমকে একটি মান নির্ধারণের মাধ্যমে সূচনা করা যেতে পারে RANDOM। যদি RANDOMসেট না করা থাকে তবে পরে এটি পুনরায় সেট করা হলেও এটি এর বিশেষ বৈশিষ্ট্যগুলি হারাতে পারে।

সুতরাং আপনি যদি ভেবেছিলেন এটি পরিবেশের পরিবর্তনশীলও ছিল, তবে এটি আপনাকে envপ্রথম বার বলা না হওয়া পর্যন্ত সেট করা হবে না। এ কারণেই এটি প্রদর্শিত হয় নি set:

$ set | grep RAN   ## returns nothing, RANDOM is unset
$ echo "$RANDOM"   ## this will assign a value to RANDOM
1234
$ set | grep RAN   ## so now it will also appear in the output of set 
RANDOM=1234

এটি একটি আকর্ষণীয় আবিষ্কার set | grep RAN। আমি এটা আশা করতাম না। এফডাব্লুআইডাব্লু, আমি বিশ্বাস করি যে ডকুমেন্টেশন দ্বারা এটি পূর্বাভাস দেওয়া যায় না।
জি-ম্যান বলছেন 'মিনিকা পুনরায় ইনস্টল করুন'

1
পিএস অভিনন্দন 120,000 পৌঁছেছেন। (আমি অনুমান করি যে আমি আপনাকে সবেমাত্র ফেলে দিয়েছি))
জি-ম্যান বলেছেন 'রিইনস্টেট মনিকা'

4

বেশিরভাগ শেলগুলিতে শেল দ্বারা সেট বা ব্যবহৃত বেশ কয়েকটি ভেরিয়েবল থাকবে যা ডিফল্টরূপে শিশু প্রসেসগুলিতে রফতানি হয় না।

বাশে কিছু স্পষ্টতই বাশ-নির্দিষ্ট রয়েছে:

$ echo "${!BASH*}"
BASH BASHOPTS BASHPID BASH_ALIASES BASH_ARGC BASH_ARGV BASH_CMDS BASH_COMMAND BASH_LINENO BASH_SOURCE BASH_SUBSHELL BASH_VERSINFO BASH_VERSION
$ echo $BASH_VERSION
4.4.12(1)-release
$ env|grep -c BASH
0

এরপর মত আরো মান বেশী OPTINDএবং OPTERR(দ্বারা ব্যবহৃত getopts), এবং PS2, PS3(সেকেন্ডারি অনুরোধ জানানো) এবং এমনকি অন্য "ম্যাজিক" পরিবর্তনশীল: SECONDS(শো সময় সেকেন্ডের মধ্যে যেহেতু শেল শুরু হয়েছিল)

বাশ-এ আপনি সমস্ত ভেরিয়েবল এবং তাদের রফতানি স্থিতি দেখতে পাবেন declare -p। যার সাথে চিহ্নিত চিহ্নিত করা হয় -xতা রফতানি করা হয়, সেগুলি ছাড়া xহয় না। (কিছুতে অন্যান্য পতাকা থাকবে যেমন iপূর্ণসংখ্যার rজন্য বা কেবল পঠনের জন্য)

Zsh বা ksh93, আপনি ব্যবহার করতে পারেন typeset -pপরিবর্তন করে, যদিও Zsh চিহ্ন রপ্তানি ভেরিয়েবল typesetথেকে exportআউটপুটে পরিবর্তে পতাকা ব্যবহার করে। exportনিজে থেকে সমস্ত রফতানি ভেরিয়েবলগুলিও প্রদর্শন করবে তবে এটি আপনি চালিয়ে যাচ্ছেন একই ফলাফল সম্পর্কে env


2

আপনি যদি এটির জন্য গুগল করেন তবে ডক্সটি নিম্নলিখিতটি উল্লেখ করে:

$RANDOMএটি একটি অভ্যন্তরীণ বাশ ফাংশন (ধ্রুবক নয়) যা 0 - 32767 সীমাতে সিউডোরোডম [1] পূর্ণসংখ্যা প্রদান করে It এটি কোনও এনক্রিপশন কী উত্পন্ন করতে ব্যবহার করা উচিত নয়।

আপনি যদি ব্যবহার করেন straceআপনি দেখতে পাচ্ছেন যে $RANDOM"ভেরিয়েবল" সরাসরি কমান্ডগুলিতে প্রেরণ করা হয়েছে যেন এটি কোনও সাধারণ শেল ভেরিয়েবল বা পরিবেশের পরিবর্তনশীল ছিল তবে এটি কেবল একটি অভ্যন্তরীণ ফাংশন যা শেলটি তৈরি করেছে, বাশ, এটি সম্প্রসারণ করছে।

$ strace -t echo "random value: $RANDOM"
04:37:58 execve("/bin/echo", ["echo", "random value: 30795"], [/* 27 vars */]) = 0
04:37:58 brk(NULL)                      = 0x19c1000
04:37:58 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f9841351000
...

বনাম এই নিয়মিত পরিবর্তনশীল:

$ strace -t echo "random value: $SOMEVAR"
04:40:19 execve("/bin/echo", ["echo", "random value: helloworld"], [/* 27 vars */]) = 0
04:40:19 brk(NULL)                      = 0x154b000
04:40:19 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f659d2eb000
...

পরিবর্তনশীল একটি রেফারেন্স হিসাবে পাস করা হচ্ছে না।

তথ্যসূত্র


1
ঠিক আছে, কমান্ড লাইন আর্গুমেন্টের $RANDOMবা তার প্রসারিত মানটি পাস করা $SOMEVARএবং পরিবেশের পরিবর্তনশীল হিসাবে নয়? আপনার exportউভয়ের পরিবেশের মধ্য দিয়ে যেতে হবে।
ইলকচাচ

না যে কোন পার্থক্য করতে হবে। শেল তাদের নির্বিশেষে প্রসারিত করে। আমি এটি যেভাবে দেখিয়েছি তা মূলত শেলটি সম্প্রসারণ করছে তা হাইলাইট করে।
slm

2
straceআউটপুট শেল দ্বারা চালানো অভ্যন্তরীণ ফাংশন ধরতে মনে হচ্ছে না। উভয় ক্ষেত্রেই চলকটি এর প্রথম লাইনে ইতিমধ্যে প্রসারিত হয়েছে strace। আমি বুঝতে পারছি না আপনি কী পার্থক্য দেখিয়েছেন। আমি কী মিস করছি?
টেরডন

$RANDOMঅভ্যন্তরীণভাবে শেল থেকে সম্প্রসারণ করা হচ্ছে তা দেখানো হচ্ছে । এটি মূলত নিশ্চিতকরণ যে শেলটি মান নির্ধারণ করছে এবং কোনও ভেরিয়েবলের রেফারেন্স দিচ্ছে না। শেল যখন পার্স নির্বাহ করতে কমান্ড লাইনটি $RANDOMপ্রসারিত করে এবং প্রসারিত ফর্মটি এতে পাস করে echo
slm

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