सीडी एक कार्यक्रम क्यों नहीं है?


128

मैंने हमेशा सोचा है कि cdकोई कार्यक्रम क्यों नहीं है, लेकिन कभी भी उत्तर खोजने में कामयाब नहीं हुआ।

किसी को पता है कि यह मामला क्यों है?



1
मुझे याद है कि पढ़ना (मुझे नहीं मिल रहा है) कि मूल यूनिक्स cdकमांड एक अलग कार्यक्रम था। खोल ने इसे विशेष रूप से संभाला कि यह नहीं fork, बस exec। और जब cdकिया गया था, यह निष्पादित करेगा sh। मुझे नहीं पता कि यह एक सच्ची कहानी है।
कैमह

क्या उल्लेख होगा? यदि यह विशेष हैंडलिंग को जोड़ने वाला है, तो यह केवल chdirsyscall को कॉल कर सकता है। सूत्रों का कहना है: v1 v5 v7 (बॉर्न शेल के साथ पहला संस्करण)
मिकेल

2
@camh, यह एक सच्ची कहानी है। मैंने वह भी डेनिस एम। रिची द्वारा लिखे गए एक लेख में पढ़ा है, "द इवोल्यूशन ऑफ द यूनिक्स टाइम-शेयरिंग सिस्टम", एटी एंड टी बेल लेबोरेटरीज टेक्निकल जर्नल 63 (6), पार्ट 2, 1984.
jlliagio

@ मिकेल: मैं मानता हूं कि यह व्यर्थ प्रतीत होता है, लेकिन मैं बस एक कहानी के बारे में रिले cdकर रहा था जिसे मैंने पढ़ा था। मैं इसके पहलू के बारे में स्पष्ट रूप से गलत था, अब @jlliagre ने विवरणों को भर दिया है।
camh

जवाबों:


171

cdआदेश "वर्तमान कार्यशील निर्देशिका", सही को संशोधित करता है?

"वर्तमान कामकाजी निर्देशिका" एक ऐसी संपत्ति है जो प्रत्येक प्रक्रिया के लिए अद्वितीय है।

तो, अगर cdयह एक कार्यक्रम था तो यह इस तरह काम करेगा:

  1. cd foo
  2. cdप्रक्रिया प्रारंभ
  3. cdप्रक्रिया निर्देशिका में परिवर्तन सीडी की प्रक्रिया के लिए
  4. cdप्रक्रिया से बाहर निकलता है
  5. आपके शेल में अभी भी वही स्थिति है, जिसमें वर्तमान वर्किंग डायरेक्टरी शामिल है, जो आपने शुरू करने से पहले किया था।

8
आपके पांच चरण सही हैं, लेकिन "यदि cdकोई प्रोग्राम होता तो वह इस तरह काम करता" जब होना चाहिए "जब cdइसका बाहरी प्रोग्राम कार्यान्वयन में उपयोग किया जाता है, तो यह इस तरह काम करता है"।
jlliagre

1
सिस्टम प्रोग्रामर नहीं होने के नाते, और न ही वास्तव में भारतीय नौसेना पोत और शेल के साथ बातचीत करने का गहरा ज्ञान होने के कारण, मैंने शेल को इसकी वर्तमान कार्यशील निर्देशिका को उजागर करने की उम्मीद की होगी, और सीडी एक प्रोग्राम होगा जो उस संपत्ति तक पहुंच और बदल देता है। इस उत्तर को देखने के बाद समझना, कि शायद यह सब-इष्टतम है कि यह वास्तव में कई कारणों से कैसे काम करता है।
जेसन

108

cdशेल बिलिन होने के अलावा, वास्तव में POSIX अनुरूप ओएस पर एक कार्यक्रम भी है । उन्हें नियमित उपयोगिताओं के लिए स्वतंत्र निष्पादनयोग्य प्रदान करना चाहिए , जैसे cd। यह उदाहरण के लिए Solaris , AIX , HP-UX और OS X के साथ मामला है ।

जाहिर है, एक बिल्डिन cdअभी भी अनिवार्य है क्योंकि इसका बाहरी कार्यान्वयन वर्तमान शेल निर्देशिका को नहीं बदलता है। हालांकि, उत्तरार्द्ध अभी भी उपयोगी हो सकता है। यहाँ एक उदाहरण दिखाया गया है कि कैसे POSIX कल्पना करता है कि इस cdकमांड का उपयोग कैसे किया जा सकता है:

find . -type d -exec cd {} \;

POSIX सिस्टम पर, यह ऑनलाइनर उन सभी निर्देशिकाओं के लिए एक त्रुटि संदेश की सूचना देगा, जिनमें आपको अनुमति नहीं cdहै। अधिकांश Gnu / Linux वितरण में, यह उस त्रुटि संदेश के साथ विफल रहता है:

find: `cd': No such file or directory

और यहाँ आपके प्रश्न का उत्तर है, " सीडी एक कार्यक्रम क्यों नहीं है? " मूल यूनिक्स के सह-लेखक द्वारा। बहुत प्रारंभिक यूनिक्स कार्यान्वयन पर, cd( chdirउस समय वर्तनी ) एक बाहरी कार्यक्रम था। यह forkपहली बार लागू होने के बाद अप्रत्याशित रूप से काम करना बंद कर दिया ।

उद्धरण डेनिस रिची :

हमारे जुबली के बीच में, यह पता चला था कि chdir (वर्तमान धारा परिवर्तन) कमांड ने काम करना बंद कर दिया था। कोड के बारे में बहुत कुछ पढ़ा गया था और चिंताजनक आत्मनिरीक्षण किया गया था कि कैसे कांटा के अलावा chdir कॉल को तोड़ सकता है। अंत में सच्चाई सामने आई: पुरानी व्यवस्था में चदिर एक साधारण आदेश था; यह टर्मिनल से जुड़ी (अद्वितीय) प्रक्रिया की वर्तमान निर्देशिका को समायोजित करता है। नई प्रणाली के तहत, chdir कमांड ने इसे निष्पादित करने के लिए बनाई गई प्रक्रिया की वर्तमान निर्देशिका को सही ढंग से बदल दिया, लेकिन इस प्रक्रिया को तुरंत समाप्त कर दिया और इसका मूल शैल पर कोई प्रभाव नहीं पड़ा! शेल के भीतर आंतरिक रूप से निष्पादित चिरिर को एक विशेष कमांड बनाना आवश्यक था। यह पता चलता है कि कई कमांड जैसे कार्यों में समान संपत्ति होती है, उदाहरण के लिए लॉगिन।

स्रोत: डेनिस एम। रिची, " द इवोल्यूशन ऑफ़ द यूनिक्स टाइम-शेयरिंग सिस्टम ", एटी एंड टी बेल लेबोरेटरीज टेक्निकल जर्नल 63 (6), पार्ट 2, 1984 अक्टूबर, पीपी.1577-93

यूनिक्स संस्करण 1 (मार्च 1971) chdir मैनुअल पेज बताता है:

क्योंकि प्रत्येक कमांड को निष्पादित करने के लिए एक नई प्रक्रिया बनाई जाती है, यदि सामान्य कमांड के रूप में लिखा जाता है तो chdir अप्रभावी होगा। इसलिए इसे शेल द्वारा पहचाना और निष्पादित किया जाता है।


10
... इसलिए, जाहिरा तौर पर, POSIX यह कहता है कि एक स्वतंत्र cdनिष्पादन योग्य होगा, लेकिन यह कुछ भी नहीं करेगा (गलत तर्कों के साथ संभवतः त्रुटि संदेशों को छोड़ दें) को छोड़कर। अजीब।
इल्मरी करोनें

4
ओह, अगर यह सच है, तो यह पॉसिक्स में बेवकूफी नहीं होगी।
काज

5
POSIX सीडी पेज भी कहते हैं, "जब से सीडी वर्तमान खोल निष्पादन वातावरण को प्रभावित करता है, यह हमेशा एक खोल नियमित निर्मित के रूप में प्रदान की जाती है।"।
मिकेल

6
@ काज़, वे पूरी तरह से अलग चीजें नहीं हैं। वे एक ही काम करते हैं लेकिन केवल बिल्टइन वर्तमान शेल को प्रभावित करता है।
जूलियाग्रे

13
@ काज: कृपया मुझे मूर्ख मत कहो जबकि मैं सिर्फ एक तथ्य की रिपोर्ट कर रहा हूं। आप POSIX से सहमत या असहमत हो सकते हैं लेकिन दूत को गोली नहीं मार सकते।
जूलियाग्रे

47

बैश परिचय से ( एक शेल क्या है? ):

शेल अलग-अलग उपयोगिताओं के माध्यम से प्राप्त करने के लिए असंभव या असुविधाजनक कार्यशीलता को लागू करने वाले अंतर्निहित आदेशों (अंतर्निहित) का एक छोटा सा सेट भी प्रदान करते हैं। उदाहरण के लिए, cd, break, continue, और exec) खोल के बाहर से लागू नहीं किया जा सकता क्योंकि वे सीधे खोल ही में हेरफेर। history, getopts, kill, या pwdbuiltins, दूसरों के बीच, अलग उपयोगिताओं में लागू किया जा सकता है, लेकिन वे और अधिक के रूप में निर्मित आदेशों का उपयोग करने के लिए सुविधाजनक है। शेल के सभी निर्माण बाद के खंडों में वर्णित हैं।


29

इस साल अप्रैल फूल के लिए, मैंने एक स्टैंडअलोन संस्करणcd लिखा ।

किसी को मजाक नहीं सूझा। आह।

जो कोई भी निश्चित नहीं है कि cdइसे शेल में बनाया जाना चाहिए, इसे डाउनलोड करना चाहिए, इसका निर्माण करना चाहिए और इसे आज़माना चाहिए।

इसके मैन पेज को भी पढ़ें। :)


वास्तव में उपयोगी कोड! :-)
dschulz

6
अच्छा है कि आप किसी को Gnu / Linux को अधिक POSIX अनुरूप बनाने के लिए काम करते हुए देखें। आपका कार्यान्वयन न केवल एक अच्छा मजाक है, बल्कि वास्तव में लिनक्स वितरण से कुछ गायब है ...
jlliagre

8
मुझे लगता है कि मैं पोसिक्स मुद्दे का हवाला देते हुए अगले साल फिर से कोशिश करने जा रहा हूं। ;)
वॉरेन यंग

6 साल बाद: ठीक है, क्या आपने?
पीटर ए। श्नाइडर

@ पीटरए। श्नाइडर: मुझे लगा कि यह स्पष्ट है कि मैं मजाक कर रहा था, इसलिए स्पष्ट होना चाहिए, नहीं, मैं वास्तव में इस तरह के साइगविन जैसे ओएस और ओएस जैसी परियोजनाओं में लाने के प्रयास में खर्च करने वाला नहीं हूं। कमी है /bin/cd। यदि आप मेरा कोड लेना चाहते हैं और अपनी खुद की निजी खोज करना चाहते हैं, तो ऐसा करने के लिए आपका स्वागत है।
वारेन यंग

4

cdखोल में आदेश एक अलग प्रक्रिया नहीं हो सकता एक अलग प्रक्रिया (भी नहीं माता पिता प्रक्रिया) की वर्तमान कार्यशील निर्देशिका को बदलने की कोई व्यवस्था नहीं है क्योंकि यूनिक्स में वहाँ।

यदि cdएक अलग प्रक्रिया थी तो उसे अपने मूल (शेल) की वर्तमान कार्यशील निर्देशिका को बदलना होगा जो कि यूनिक्स में संभव नहीं है। इसके बजाय cdएक विशेष कमांड में बनाया गया है। शेल अपने वर्तमान कार्य निर्देशिका को बदलने chdir()और fchdir()बदलने का कार्य करता है ।

नोट: कर्नेल हर प्रक्रिया के लिए वर्तमान कार्य निर्देशिका की इनकोड संख्या संग्रहीत करता है। बच्चे की प्रक्रिया cwdअपने माता-पिता से विरासत में मिली है ।


0

सीडी एक शेल निर्मित कमांड है। जितना आसान है। आदमी सीडी यह सब कहता है। सीडी कमांड सभी दुभाषियों के लिए और (थ्रेडेड वातावरण में) सभी थ्रेड्स के लिए वर्किंग डायरेक्टरी में बदलाव करता है।


क्योंकि शेल वह वातावरण है जो आपके वर्तमान कार्यशील dirs ($ PDW ...) या cdable_vars के बारे में ध्यान रखता है। यह बिल्टिन अंततः वह तरीका है जिससे सभी उपयोगकर्ता-दृश्यमान कमांड को वर्तमान कार्य निर्देशिका को बदलना चाहिए। आप इसे इस तरह से परख सकते हैं: सीडी के बिना बैश को संकलित करें और अपनी स्वयं की सीडी स्क्रिप्ट लिखने का प्रयास करें, जो सभी पर्यावरण cdable_vars की देखभाल करने की कोशिश करता है। यह सवाल भी एक डेवलपर से संबंधित है। मुझे यकीन है कि वे आपको इस सवाल का और अधिक गहराई से जवाब दे सकते हैं।

2
एक बहुत अच्छा तकनीकी कारण है cdजो अंतर्निहित है। मेरा सुझाव है कि आप उच्चतम रैंक वाले उत्तर पढ़ें और विचार करें कि आपके उत्तर को कैसे बेहतर बनाया जा सकता है।
थोरबजोरन रावन एंडरसन

उच्चतम रैंक वाला उत्तर सबसे खराब था जो मैंने कभी पढ़ा था! लेकिन हुह? मैं कौन हूँ!

3
लेकिन यह सवाल का जवाब क्यों देता है
थोरबजोरन रेव एंडरसन

-1

मुझे लगता है कि लोगों के उत्तर में एक बात याद आ रही है कि वर्तमान निर्देशिका एक पर्यावरण चर है जिसे प्रत्येक कार्यक्रम बदल सकता है। यदि आप अपने वर्तमान परिवेश चर सूची को देखने के लिए 'निर्यात' कमांड का उपयोग करते हैं, तो आपके पास होगा:

declare -x PWD="/home/erfan"

आपके परिणामों में इस प्रकार 'सीडी' कमांड से हम केवल इस आंतरिक चर को संशोधित करना चाहते हैं। मुझे लगता है कि अगर हम कोशिश करते हैं, तो हम शेल में किसी भी pty के PWD वैरिएबल का पीछा कर सकते हैं, बेशक। पसंद:

cder    #change current PTY $PWD variable

लेकिन मुझे लगता है कि सामान्य मामलों में कोई जरूरत नहीं है। दूसरे शब्द में, हम परिभाषित आंतरिक संस्करण को संशोधित करने के लिए बैश (या किसी शेल) से मदद लेते हैं।


3
हालांकि यह सच है कि बॉर्न शेल मौजूदा कार्य निर्देशिका (CWD) को $ PWD के रूप में उजागर करते हैं, जो कि प्राथमिक भंडारण स्थान नहीं है; वास्तविक स्थान कर्नेल की प्रति-प्रक्रिया संरचना में है। इसलिए यह कहना गलत है कि CWD "एक पर्यावरण चर है।" यदि यह आपके सुझाव देने के तरीके पर काम करता है, तो यह C टू-लाइनर ..पथ को प्रिंट करेगा , न कि जिस पथ से आपने इसे शुरू किया है: #include <stdlib.h> int main(void) { chdir(".."); puts(getenv("PWD")); }(C गोले CWD को% cwd के बजाय, वैसे ही उजागर करते हैं।)
वॉरेन यंग

अपने ऐप में कुछ और लाइनें जोड़ने की सुविधा देता है। #include <stdlib.h> int main (शून्य) {chdir (".."); पुट (getenv ( "पीडब्ल्यूडी")); setenv (P "PWD", "/", 1); पुट (getenv ( "पीडब्ल्यूडी")); } परिणाम के रूप में हमारे पास क्या होगा?
इरफंकम

3
यह सिर्फ CWD पर कोई साइड इफेक्ट के साथ एक वैरिएबल के मूल्य को अधिलेखित करेगा। यह दिखाने के लिए एक बेहतर परीक्षण है: #include <unistd.h> int main(void) { char ac[99]; setenv("PWD", "/", 1); puts(getcwd(ac, sizeof(ac))); }यह उस निर्देशिका को दिखाएगा जिसे आपने प्रोग्राम शुरू किया था, नहीं /
वॉरेन यंग

मुझे लगता है कि प्रत्येक प्रक्रिया में एक कार्यशील निर्देशिका और पथ चर भी है। इस प्रकार आप chdir द्वारा प्रक्रिया की इस विशेषता को बदल देते हैं। शेल में यह विशेषता भी है और सीडी द्वारा हम इस एट्रिब्यूशन को संशोधित करते हैं।
इरफंकम

4
नहीं, मैं आपको बता रहा हूं कि $PWDकेवल बॉर्न शेल का अर्थ है। यह शेल के लिए एक तरीका है कि वह कुछ ऐसी चीज़ों को जानता है जो शेल स्क्रिप्ट को जानता है इसलिए उन्हें pwdइसे खोजने के लिए कॉल नहीं करना पड़ता है। मूल्य के आधार पर कोई भी स्टैंडअलोन कार्यक्रम $PWDअविश्वसनीय होगा।
वॉरेन यंग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.