जवाबों:
एक वातावरण उतना जादुई नहीं है जितना यह प्रतीत हो सकता है। शेल इसे मेमोरी में स्टोर करता है और execve()
सिस्टम कॉल को पास करता है। बाल प्रक्रिया इसे एक सरणी सूचक के रूप में विरासत में मिली है जिसे कहा जाता है environ
। से execve
मैनपेज:
SYNOPSIS
#include <unistd.h> int execve(const char *filename, char *const argv[], char *const envp[]);
argv
नए कार्यक्रम के लिए तर्क तार की एक सरणी है।
कन्वेंशन द्वारा, इन स्ट्रिंग्स में से सबसे पहले फ़ाइल नाम से संबंधित फ़ाइल नाम निष्पादित होना चाहिए।envp
स्ट्रिंग्स की एक सरणी है, पारंपरिक रूप से कुंजी = मूल्य, जो नए प्रोग्राम के लिए पर्यावरण के रूप में पारित किए जाते हैं।
environ(7)
मैनपेज भी कुछ अंतर्दृष्टि प्रदान करता है:
SYNOPSIS
extern char **environ;
विवरण
चर
environ
"पर्यावरण" नामक तारों के संकेत की एक सरणी को इंगित करता है। इस सरणी में अंतिम पॉइंटर का मान हैNULL
। (यह चर उपयोगकर्ता प्रोग्राम में घोषित किया जाना चाहिए, लेकिन शीर्ष लेख में यह घोषित किया जाता है कि<unistd.h>
यदि शीर्ष लेख फाइलें libc4 या libc5 से आती हैं, और मामले में वे glibc से आते हैं और _GNU_SOURCE परिभाषित किया गया था।) प्रक्रिया द्वारा निष्पादित (3) कॉल जिसने प्रक्रिया शुरू की।
ये दोनों GNU मैनपेज़ POSIX विनिर्देश से मेल खाते हैं
exec*e
वैरिएंट है जो स्पष्ट रूप से environ
वैश्विक चर का उपयोग करते हुए, बजाय एक एनवी पास करता है । v
"वेक्टर" का अर्थ है, और एक सरणी के रूप में पारित कमांड लाइन तर्कों को संदर्भित करता है (एक "सूची" (चर-लंबाई फ़ंक्शन)) execve
एक सिस्टम कॉल है, और अन्य सभी exec*
फ़ंक्शन इसके लिए libc रैपर हैं।
आपको यह सिर्फ थोड़ा गलत लगा है: SOME_NAME=value
एक शेल वैरिएबल (अधिकांश गोले में) बनाता है। export SOME_NAME=value
एक पर्यावरण चर बनाता है। बदतर के लिए बेहतर के लिए, अधिकांश यूनिक्स / लिनक्स / * बीएसडी गोले पर्यावरण चर और शेल चर में समान सिंटैक्स का उपयोग करते हैं।
कुछ बड़े अर्थों में, एक "पर्यावरण" सिर्फ सूचना है जो कार्यक्रम के निष्पादन के साथ-साथ चलती है। सी कार्यक्रमों में, आपको एक getpid()
कॉल के साथ प्रक्रिया आईडी मिल सकती है , शेल प्रोग्राम में आप एक चर पहुंच का उपयोग करेंगे $$
:। प्रक्रिया आईडी कार्यक्रम के वातावरण का सिर्फ एक हिस्सा है। मेरा मानना है कि "पर्यावरण" शब्द कुछ और अधिक सैद्धांतिक कंप्यूटर विज्ञान विषयों से आता है, जैसे कि मॉडलिंग कार्यक्रम निष्पादन .. कार्यक्रम निष्पादन के मॉडल में एक वातावरण है "जिसमें चर और उनके मूल्यों के बीच संबंध होते हैं"।
और यह बाद की, मजबूत परिभाषा है कि यूनिक्स / लिनक्स / * बीएसडी के गोले के लिए एक "पर्यावरण" क्या है: नामों ("चर") और उनके मूल्यों के बीच एक संघ। अधिकांश यूनिक्स शैली के गोले के लिए, मान सभी वर्ण तार हैं, हालांकि यह उतना सख्ती से सच नहीं है जितना कि यह हुआ करता था। Ksh, Zsh और Bash सभी ने इन दिनों चर टाइप किया है। यहां तक कि शेल फ़ंक्शन परिभाषाएं भी निर्यात की जा सकती हैं।
सादे खोल चर से अलग पर्यावरण के उपयोग में fork/exec
एक नई प्रक्रिया शुरू करने की विधि शामिल है जिसका उपयोग सभी यूनिक्स करते हैं। जब आप export
एक नाम / मान जोड़ी बनाते हैं, तो वह नाम / मूल्य जोड़ी नए निष्पादनयोग्य के वातावरण में मौजूद होगी, जिसे शेल द्वारा execve(2)
सिस्टम कॉल के साथ शुरू किया गया था (आमतौर पर एक के बाद fork(2)
, जब exec
शेल कमांड का उपयोग किया गया था , तब छोड़कर )।
एक के बाद execve()
, main()
नए बाइनरी के कार्य में इसकी कमांड लाइन तर्क हैं, पर्यावरण ( var=value
स्ट्रिंग के लिए संकेत के एक पूर्ण-समाप्त सरणी के रूप में संग्रहीत , environ(7)
मैन पेज देखें )। विरासत में मिली अन्य अवस्थाओं में ulimit
सेटिंग्स, करंट वर्किंग डाइरेक्टरी और कोई भी ओपन फाइल डिस्क्रिप्टर शामिल है, जिसके लिए execve()
कॉलर के पास FD_CLOEXECA नहीं है। Tty की वर्तमान स्थिति (इको इनेबल्ड, रॉ मोड, इत्यादि) को नव- exec
संपादन प्रक्रिया द्वारा विरासत में प्राप्त निष्पादन राज्य का हिस्सा माना जा सकता है।
साधारण कमांड के लिए निष्पादन वातावरणbash
का मैनुअल विवरण देखें (बिलिन या शेल कार्यों के अलावा)।
यूनिक्स का वातावरण कम से कम कुछ अन्य ऑपरेटिंग सिस्टमों से अलग है: वीएमएस "लेक्सिकल" को एक बच्चे की प्रक्रिया द्वारा बदला जा सकता है, और यह परिवर्तन माता-पिता में दिखाई दे रहा था। एक cd
बच्चे की प्रक्रिया में एक वीएमएस माता-पिता की कामकाजी निर्देशिका को प्रभावित करेगा। कम से कम कुछ परिस्थितियों में, और मेरी स्मृति मुझे विफल हो सकती है।
कुछ वातावरण चर अच्छी तरह से जाना जाता है, $HOME
, $PATH
, $LD_LIBRARY_PATH
और अन्य। कुछ एक दिए गए प्रोग्रामिंग सिस्टम के लिए पारंपरिक हैं, ताकि एक माता-पिता खोल बहुत सारे और विशेष प्रयोजन के लिए बहुत सारी जानकारी पास कर सकें, जैसे कि एक विशिष्ट अस्थायी निर्देशिका, या एक उपयोगकर्ता आईडी और पासवर्ड जो दिखाई नहीं देते हैं ps -ef
। उदाहरण के लिए, साधारण सीजीआई कार्यक्रम पर्यावरण चर के माध्यम से वेब सर्वर से बहुत सारी जानकारी प्राप्त करते हैं।
SOME_NAME=value command
उस आदेश आह्वान के लिए SOME_NAME वातावरण चर सेट करेगा। भ्रामक रूप से, यह एक ही नाम के शेल चर को सेट करने के लिए प्रतीत नहीं होता है।
SOME_NAME=value command
व्यवहार आपकी अपेक्षा के विपरीत है, यह एक विशेष वाक्यविन्यास है जिसका अर्थ है "कमांड में पारित पर्यावरण में SOME_NAME जोड़ें, लेकिन अन्यथा इस शेल के चर को बदल न दें"।
fork()
एड होना चाहिए , लेकिन वे शेल वेरिएबल्स की प्राप्ति (कॉपी) करते हैं।
उनके सबसे कच्चे रूप में पर्यावरण चर नाम / मूल्य जोड़े का एक सेट है। man 1 bash
पर्यावरण अनुभाग के तहत बैश मैन पेज ( ) में वर्णित है :
When a program is invoked it is given an array of strings called the
environment. This is a list of name-value pairs, of the form
name=value.
The shell provides several ways to manipulate the environment. On
invocation, the shell scans its own environment and creates a parameter
for each name found, automatically marking it for export to child pro-
cesses. Executed commands inherit the environment.
व्यावहारिक रूप से, यह आपको ऐसे व्यवहार को परिभाषित करने की अनुमति देता है जो वर्तमान शेल से आमंत्रित किए गए कार्यक्रमों के लिए साझा या अद्वितीय है। उदाहरण के लिए, उपयोग करते समय crontab
या visudo
आप EDITOR
किसी अन्य संपादक को परिभाषित करने के लिए पर्यावरण चर को परिभाषित कर सकते हैं , जिसे आपके सिस्टम द्वारा डिफ़ॉल्ट रूप से उपयोग किया जाएगा। उसी चीज़ को सही माना जा सकता है जैसे कि man
कमांड जो आपके PAGER
वातावरण को देखने के लिए काम करती है कि मैन पेज के आउटपुट को प्रदर्शित करने के लिए पेजर प्रोग्राम का क्या उपयोग किया जाना चाहिए।
बहुत सारे यूनिक्स कमांड पर्यावरण को पढ़ते हैं और जो वहां सेट होता है, उसके आधार पर उनके आउटपुट / प्रोसेसिंग / एक्शन में बदलाव करते हैं। कुछ साझा हैं, कुछ इस कार्यक्रम के लिए अद्वितीय हैं। अधिकांश मैन पेज में जानकारी होती है कि पर्यावरण चर का वर्णित कार्यक्रम पर कैसे प्रभाव पड़ता है।
अन्य व्यावहारिक चित्र एक ही मंच पर ओरेकल के कई इंस्टॉल के साथ सिस्टम जैसी चीजों के लिए हैं। सेटिंग के द्वारा ORACLE_HOME
, ओरेकल कमांड का पूरा सूट (जैसा कि आपके PATH
पर्यावरण चर से भरा हुआ है ) फिर उस शीर्ष स्तर की निर्देशिका के तहत सेटिंग्स, परिभाषाओं, मैपिंग और लाइब्रेरीज़ को खींचें। यह अन्य कार्यक्रमों जैसे जावा के साथ JAVA_HOME
पर्यावरण चर के लिए भी सही है।
बैश में ही कई पर्यावरण चर हैं जो इतिहास ( HISTSIZE
, HISTFILE
आदि), स्क्रीन आकार ( COLUMNS
), टैब पूरा होने ( FIGNORE
, GLOBIGNORE
) लोकेल और चरित्र एन्कोडिंग / डिकोडिंग ( LANG
, LC_*
), शीघ्र ( PS1
.. PS4
) से चीजों की एक श्रृंखला के व्यवहार को बदल सकते हैं । इसलिए आगे (फिर से बैश मैन पेज से ज्ञान की तलाश करें)।
इसके अलावा, आप ऐसी स्क्रिप्ट / प्रोग्राम लिख सकते हैं जो आपके स्वयं के कस्टम वातावरण चर का उपयोग करते हैं (सेटिंग्स को पास करने, या कार्यक्षमता को बदलने के लिए)।
"पर्यावरण चर" गतिशील नामित मानों का एक समूह है जो कंप्यूटर पर चलने वाली प्रक्रियाओं को प्रभावित कर सकता है।
वे ऑपरेटिंग वातावरण का हिस्सा हैं जिसमें एक प्रक्रिया चलती है। उदाहरण के लिए, एक चल रही प्रक्रिया अस्थायी फ़ाइलों को संग्रहीत करने के लिए एक उपयुक्त स्थान की खोज करने के लिए TEMP पर्यावरण चर के मान को क्वेरी कर सकती है, या प्रक्रिया को चलाने वाले उपयोगकर्ता द्वारा स्वामित्व वाली निर्देशिका संरचना को खोजने के लिए HOME या USERPROFILE चर का उपयोग कर सकती है।
यहां अधिक जानकारी → http://en.wikipedia.org/wiki/Environment_variable ।
सब कुछ आप पर्यावरण चर के बारे में जानना चाहते हैं ... about
इस उत्तर के लिए कुछ शेल स्क्रिप्टिंग अनुभव और ज्ञान की आवश्यकता होती है, जैसे शब्द चर, मूल्य, चर प्रतिस्थापन, शीघ्र, प्रतिध्वनि, कर्नेल, शैल, उपयोगिता, सत्र और प्रक्रिया।
एक पर्यावरण चर (envar) वैश्विक परिभाषित चर का एक सेट है जो किसी दिए गए प्रक्रियाओं को कंप्यूटर के ऑपरेटिंग सिस्टम पर व्यवहार करने के तरीके को प्रभावित कर सकता है।
हम एक $
और बड़े अक्षरों के साथ दूतों को प्रतिस्थापित करते हैं । उदाहरण के लिए $PS1
:।
हम एक एनवार को इस तरह से प्रिंट कर सकते हैं:
echo $PS1
$PS1
Unix प्रॉम्प्ट का मान रखता है। कहो इसके मूल भाव हैं \u
\w
$
।
\u
(वर्तमान) उपयोगकर्ता के लिए खड़ा है,\w
कार्य निर्देशिका के लिए खड़ा है,$
प्रॉम्प्ट को बॉर्डर करना है।तो, अगर हम करते हैं: echo $PS1
, हम के मूल्यों को देखने के \u
, \w
प्लस अंत में डॉलर चिह्न।
यदि हम उस एनवार के मूल्यों को बदलते हैं, तो हम उस संदर्भ में यूनिक्स के व्यवहार को बदल सकते हैं। उदाहरण के लिए:
PS1="\w >"
अब प्रॉम्प्ट इस तरह दिखता है (कार्य निर्देशिका को "जॉन" नाम दिया गया है):
John >
उसी तरीके से हम कर सकते थे PS1="Hello, I'm your prompt >"
, इसलिए echo $PS1
लाएंगे:
Hello, I'm your prompt >
बश 4.xx में, हम env
कमांड के साथ सिस्टम में सभी एन्वार प्रिंट कर सकते हैं । मेरा सुझाव env
है कि टर्मिनल में निष्पादित करें और आउटपुट पर कुछ नज़र डालें।
एक सत्र का टर्मिनल आइए हम बैश के साथ आने वाले दूतों को अनुकूलित करें।
पूर्वोक्त परिवर्तन आमतौर पर अस्थायी हैं, और यहाँ क्यों है:
प्रत्येक सत्र (जो एक उप-सत्र नहीं है) अद्वितीय है, और कई प्रक्रियाएं एक ही समय में (प्रत्येक अपने स्वयं के सेट के साथ) विशिष्ट रूप से चल सकती हैं, लेकिन आमतौर पर सत्र 0 से सत्र 1 और ऊपर की ओर विरासत है।
एक प्रक्रिया में हम जो बदलाव करते हैं, वह इसके लिए अद्वितीय है, और अगर हम इसे किसी तरह से सहेजे बिना इसे बंद कर देंगे तो यह समाप्त हो जाएगा।
एनवार परिवर्तनों को संग्रहीत करने के लिए कई प्रकार के तरीके उपलब्ध हैं, जो हमारे द्वारा चुने गए दायरे पर निर्भर करता है। इस तरह के बदलावों के लिए अलग-अलग स्कोप (स्तर) हैं:
यूनिक्स 3 मुख्य परतों से बना है: कर्नेल, शेल और उपयोगिताओं। AFAIK प्रत्येक खोल के अपने स्वयं के दूत होते हैं, और ये मुख्य रूप से या विशेष रूप से शेल में निर्मित होते हैं।
विशिष्ट स्थान जिसमें विश्व स्तर पर इनका परिवर्तन होता है, आमतौर पर /etc/profile
हालांकि हम ऐसा कर भी सकते हैं .bashrc
।
हम नए वातावरण बना सकते हैं और यहां एक तरीका है; 4. बैश 4.xx में कोई देशी एन्वार नाम नहीं है MESSAGE
(जैसा कि कहा गया है, एन्वार आमतौर पर बड़े होते हैं)।
MESSAGE="Hello world!"
इसे हमारे लिए बनाएंगे, और अब यदि हम प्रतिध्वनि टाइप करते हैं $MESSAGE
, तो हम प्राप्त करते हैं hello world!
।
यदि हम bash
अपने वर्तमान कार्य सत्र (विंडो) में निष्पादित करेंगे , तो हम एक नया बैश उप-सत्र शुरू करेंगे और जब तक हम निष्पादित नहीं करेंगे, तब तक मूल प्रक्रिया में काम नहीं करेंगे exit
।
नोट: एक टर्मिनल एमुलेटर (जैसे कि उबंटू डेस्कटॉप) के साथ ऑपरेटिंग सिस्टम में, एक उप-सत्र आमतौर पर एक ही विंडो पर चलता है, लेकिन दूसरी विंडो में एक नया सत्र मौजूदा एक का उप-सत्र नहीं है (यह एक आसन्न प्रक्रिया है) ।
नोट: envar मानों में विशेष संकेतों का उपयोग न करें जैसे! या उन्हें बचाया नहीं जाएगा।
हम अभी भी पहले सत्र में बनाए गए एनवार का उपयोग कर सकते हैं, दूसरे में भी इसे उपयोगकर्ता या वैश्विक स्तर की गोपनीय फाइलों में दर्ज किए बिना (निम्न डेटा देखें)। यहाँ है कि कैसे करना है:
मूल सत्र पर जाएं (वर्तमान विंडो या किसी अन्य पर) और निष्पादित करें:
export MESSAGE
निर्यात करते समय, $
साइन का उपयोग न करें।
अब इसे सभी उप-सत्रों में निर्यात किया जाता है। यदि आप echo $MESSAGE
उप-सत्र पर करेंगे , चाहे वह आपके उपयोगकर्ता या किसी अन्य से हो, तो इसे मुद्रित किया जाएगा।
ध्यान दें कि शेल आंतरिक चर जैसे PS1
निर्यात नहीं किया जाना चाहिए, लेकिन यदि आप उन्हें किसी भी कारण से निर्यात करना चाहते हैं और वे दिखाई नहीं देते हैं, तो bash
बाद में निष्पादित न करें export
, बल्कि bash –norc
।
$PATH
envar है कि उपयोगकर्ताओं को आमतौर पर सबसे बदल जाएगा।
यदि हम echo $PATH
, हम इस धारा को देखने जा रहे हैं:
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
इस एनवर के मुद्रित मूल्य कॉलन (:) द्वारा अलग किए जाते हैं, लेकिन यहां संभावित रूप से अधिक आरामदायक तरीका है (ये समान मूल्य हैं):
/usr/local/bin
/usr/bin
/bin
/usr/local/games
/usr/games
जब हम एक उपयोगिता चलाते हैं, तो ये खोज करने के लिए direcotries हैं।
निष्पादित करने से which echo
हमें इसकी फ़ाइल लोकेशन मिल जाएगी - उदाहरण के लिए, हम देख सकते हैं कि यह मौजूद है /bin/echo
।
उसके आधार पर हमें इवान के मूल्यों को देखने के लिए इको एनवार टाइप करने की आवश्यकता नहीं है। हम भी कर सकते हैं:
/bin/echo $ENVAR
Envar अभी भी निष्पादित किया जाएगा, उदाहरण के लिए:
/bin/echo $HOME
हमें देता है
/home/User || /root
जिस प्रकार:
echo $HOME
हमें देता है
/home/User || /root
नोट: $HOME
संक्षिप्त रूप में है ~
।
बैश 4.xx में, जब हम किसी उपयोगिता को उसके पूर्ण पथ के बिना उपयोग करते हैं, तो सिस्टम उपरोक्त सभी 6 मानों का उपयोग करेगा, $PATH
एनवार का। तो, यह से शुरू होगा /user/local/bin
, और echo
निष्पादन योग्य की तलाश में अपनी सभी सामग्री का पालन करेगा ।
इस मामले में, यह बंद हो जाएगा /bin/echo
, जिसमें, इस मामले में, निष्पादन योग्य रहता है।
इसलिए, मुख्य कारण जिसे हम $PATH
एनवार को अनुकूलित कर सकते हैं , निष्पादन योग्य स्थापित कर रहा है जो कि इसके मूल मूल्यों के तहत नहीं हैं।
इस तरह के निष्पादनयोग्य स्थापित करने के बाद, हमें उनके $PATH
अनुसार मूल्य निर्धारित करना चाहिए और फिर हम उनके साथ काम करने में सक्षम होंगे।
$PATH
:हम इस तरह export $PATH
से उप-सत्र (जिसमें वर्डप्रेस के लिए WP-CLI या Drupal के लिए Drush के लिए bash एक्सटेंशन शामिल हैं) को बैश कर सकते हैं :
export PATH="/home/John:$PATH"
यह एक नई मूल्य जोड़ देगा /home/John
करने के लिए $PATH
, और फिर सही बाद में, यह किसी भी देशी मूल्यों यह करने के लिए है, जो वाक्य रचना के तहत जमा हो जाती है (सही कोलन के बाद) अनुलग्नक जाएगा $PATH
।
इस तरह के स्थायी परिवर्तन को प्रासंगिक स्क्रिप्ट में, आमतौर पर /etc/profile
नाम के तहत और नीचे किया जा सकता है .bashrc
।
!
एक पर्यावरण चर मूल्य के बारे में चेतावनी जो काम नहीं कर रहा है जो इसे काम करने वाले एक उदाहरण के ठीक नीचे है, उप-सत्रों की एक गलत धारणा, क्या करना है के बारे में काफी विचित्र सलाह शेल चर, और वैश्विक पर्यावरण चर की एक गलत धारणा के निर्यात के बाद।
warning about ! in an environment variable value not working that is right below an example showing it working
? कृपया उदाहरण दें।
quite bizarre advice about what to do after exporting a shell variable
, आपका सही सही क्या मतलब है?
false notion of global environment variables
, आपका सही सही क्या मतलब है?
exec(3)
परिवार के कुछ सदस्य (अर्थात जो निष्पादन * v से मेल नहीं खाते हैं) पास हो जाते हैं ** कवर के तहत environ।