$ RANDOM को 'env' के आउटपुट में शामिल क्यों नहीं किया गया है?


23

मुझे पता envहै कि एक शेल कमांड है, इसका उपयोग वर्तमान पर्यावरण चर की सूची को प्रिंट करने के लिए किया जा सकता है। और जहां तक ​​मैं समझता हूं, RANDOMपर्यावरण चर भी है।

तो क्यों, जब मैं envलिनक्स पर लॉन्च करता हूं, तो क्या आउटपुट शामिल नहीं है RANDOM?


4
envयह शेल कमांड नहीं है क्योंकि यह आमतौर पर शेल में नहीं बनाया जाता है।
विद्वान

बैश के लिए @schily BTW, declare -xशेल बिलिन में बराबर है।
वेजेंड्रिया

जवाबों:


42

RANDOMएक पर्यावरण चर नहीं है। यह कुछ शेल द्वारा बनाए गए शेल वेरिएबल है। यह आम तौर पर डिफ़ॉल्ट रूप से निर्यात नहीं किया जाता है। यही कारण है कि यह के उत्पादन में नहीं दिखा है env

एक बार इसका उपयोग कम से कम एक बार करने के बाद, यह आउटपुट में दिखाई देगाset , जो स्वयं, शेल शेल (और फ़ंक्शंस) और वर्तमान शेल सत्र में उनके मूल्यों को सूचीबद्ध करता है। यह व्यवहार शेल पर निर्भर है और pdkshOpenBSD पर उपयोग कर रहा है, भले ही पहले उपयोग नहीं RANDOMकिया गया हो , तब भी इसे सूचीबद्ध किया जाएगा set


इस जवाब की बाकी चिंताएं हैं कि क्या होने की उम्मीद की जा सकती है अगर RANDOMनिर्यात किया गया था (यानी एक पर्यावरण चर में बदल गया)।

इसके साथ निर्यात export RANDOMकरने से यह एक पर्यावरण चर बन जाएगा, लेकिन इसका उपयोग गंभीर रूप से सीमित होगा क्योंकि एक बच्चे की प्रक्रिया में इसका मूल्य "यादृच्छिक लेकिन स्थिर" होगा (इसका अर्थ यह अपरिवर्तित यादृच्छिक संख्या होगी)। सटीक व्यवहार गोले के बीच भिन्न होता है।

मैं pdkshनीचे दिए गए उदाहरण में OpenBSD पर उपयोग कर रहा हूं और मुझे प्रत्येक 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आपके पास इसका उपयोग करने से पहले भी एक मूल्य है? मैंने हमेशा यह मान लिया था कि जब यह कहा जाता है तो केवल आबादी थी।
terdon

1
यह नहीं है, मार मैनुअल इसका उल्लेख करता है।
terdon

1
हालाँकि अगर आप ऐसा करते हैं export RANDOMया declare -p RANDOMयह प्रकट होता है, तो मुझे यकीन नहीं है कि यदि इसका कोई उपयोग है तो यह संदर्भित होने से पहले मौजूद नहीं है ...
ilkkachu

1
"एक बच्चे की प्रक्रिया में इसका मूल्य यादृच्छिक होगा, लेकिन स्थिर।" यदि यह स्थिर है, तो यह यादृच्छिक नहीं है , चाहे वह तीन बाइट्स हो या सोलह।
l0b0

3
@ l0b0 यह इस अर्थ में यादृच्छिक होगा कि आप इसकी भविष्यवाणी नहीं कर पाएंगे। जाहिर है, एक बार जब आप इसे पढ़ लेते हैं, तो यह किसी भी लंबे समय तक यादृच्छिक नहीं होता है क्योंकि यह नहीं बदलेगा (जब तक कि जैसा मैंने दिखाया, फिर से निर्यात नहीं होता है, उस स्थिति में पर्यावरण चर को एक नया यादृच्छिक मूल्य मिलेगा)। यही कारण है कि मैंने कहा कि यह यादृच्छिक लेकिन स्थिर है। मैंने इसे अब कुछ हद तक पाठ में स्पष्ट किया है।
Kusalananda

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। मुझे इसकी उम्मीद नहीं थी। FWIW, मेरा मानना ​​है कि यह प्रलेखन द्वारा भविष्यवाणी नहीं की जा सकती है।
जी-मैन का कहना है कि 'मोनिका'

1
120,000 तक पहुंचने पर PS बधाई। (मुझे लगता है मैं तुम्हें बस डाल दिया।)
जी-मैन ने कहा कि मोनिका '

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] पूर्णांक लौटाता है । इसका उपयोग एन्क्रिप्शन कुंजी उत्पन्न करने के लिए नहीं किया जाना चाहिए।

यदि आप उपयोग करते हैं, 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पर्यावरण के माध्यम से उन्हें पारित करने के लिए दोनों की आवश्यकता होगी ।
इलकाछू

नहीं, इससे कोई फर्क नहीं पड़ेगा। खोल उन्हें परवाह किए बिना फैलता है। जिस तरह से मैंने दिखाया वह मूल रूप से इस तथ्य को उजागर कर रहा है कि शेल विस्तार कर रहा है।
स्लम

2
straceउत्पादन खोल द्वारा चलाए आंतरिक समारोह को पकड़ने के लिए प्रतीत नहीं होता। दोनों ही मामलों में, चर का विस्तार पहले से ही की पहली पंक्ति में किया जा चुका है strace। मुझे समझ नहीं आ रहा है कि आप किस अंतर की ओर इशारा कर रहे हैं। मुझे किसकी याद आ रही है?
terdon

यह दिखाते हुए कि $RANDOMशेल में आंतरिक रूप से विस्तार किया जाता है। यह मूल रूप से पुष्टि करता है कि शेल मूल्य का निर्धारण कर रहा है, और एक चर के संदर्भ को पारित नहीं कर रहा है। जब यह कमांड लाइन का विस्तार पर्स को निष्पादित करने के लिए करता है $RANDOMऔर विस्तारित रूप को पास करता है echo
स्लम

2
तो, एक पर्यावरण चर की तरह कुछ भी नहीं है ।
टोबे स्पाइट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.