शेल स्क्रिप्ट में "सीडी" काम क्यों नहीं करता है?


43

मैं सिर्फ एक स्क्रिप्ट लिखना चाहता हूं जो मेरी निर्देशिका को बदल दे

मैंने फाइल में नीचे कमांड डाल दी /home/alex/pathABC

#!/bin/sh
cd /home/alex/Documents/A/B/C
echo HelloWorld

मैंने किया chmod +x pathABC

टर्मिनल में, जबकि /home/alex, मैं दौड़ता हूं ./pathABC, लेकिन आउटपुट सिर्फ है HelloWorldऔर वर्तमान निर्देशिका नहीं बदली गई है।

तो क्या गलत है?


जवाबों:


74

जैसा कि अन्य लोगों ने समझाया है, निर्देशिका को आपकी स्क्रिप्ट की बाल प्रक्रिया में बदल दिया जाता है, न कि उस टर्मिनल प्रक्रिया में जिससे स्क्रिप्ट को कहा जाता है। बाल प्रक्रिया के मरने के बाद, आप उस टर्मिनल में वापस आ जाते हैं, जहां वह बचा था।

कई विकल्प:

1. प्रतीकात्मक लिंक

जिस घर तक आप आसानी से पहुँचना चाहते हैं, उस लंबे रास्ते पर अपने घर में एक सिमलिंक लगाएं

$ ln -s /home/alex/Documents/A/B/C ~/pathABC

इसके बाद निर्देशिका को एक्सेस करें:

$ cd ~/pathABC

2. उपनाम

अपने ~ / .bashrc में एक उपनाम रखें:

alias pathABC="cd /home/alex/Documents/A/B/C"

( यहां से )

3. समारोह

एक फ़ंक्शन बनाएं जो निर्देशिका को बदलता है, फ़ंक्शन आपके टर्मिनल की प्रक्रिया में चलता है और फिर अपनी निर्देशिका को बदल सकता है।

( यहां से )

4. बच्चे की तरह दौड़ने से बचें

इसे चलाने के बजाय अपनी स्क्रिप्ट का स्रोत। सोर्सिंग (द्वारा किया .या किया गया source) स्क्रिप्ट को अपने स्वयं के सब-रन में चलाने के बजाय उसी शेल में निष्पादित किया जाता है।

$ . ./pathABC

( यहां और यहां से )

5. सीडी-सक्षम संस्करण

cdable_varsअपने में विकल्प सेट करें ~/.bashrcऔर निर्देशिका के लिए एक पर्यावरण चर बनाएँ:

shopt -s cdable_vars
export pathABC="/home/alex/Documents/A/B/C"

तब आप उपयोग कर सकते हैं cd pathABC

( यहां से )


15
अब मुझे इसका उपयोग समझ में आया source! मैं हमेशा सोचता था कि मैं ऐसा क्यों करता हूं source .bashrcऔर नहींbash .bashrc
hytromo

विकल्प 3 ने बहुत अच्छा काम किया। मैंने अपनी स्क्रिप्ट की शुरुआत में एक फ़ंक्शन go_to_wherever () {cd my / directory} को परिभाषित किया। उस निर्देशिका में संचालन चलाने से पहले इसे कॉल किया।
i9797i

> 5. सीडी-सक्षम संस्करण - है ना cd $pathABC?
लक्सैक्स

7

जब आप किसी टर्मिनल में स्क्रिप्ट चलाते हैं, तो एक चाइल्ड प्रोसेस चलती है। इस बच्चे के कार्यक्रम में अर्थात आपकी स्क्रिप्ट जो भी निर्दिष्ट निर्देशिका में बदल जाएगी। लेकिन मूल प्रक्रिया में जहां आप स्क्रिप्ट चलाते हैं वह अभी भी पुराने रास्ते में है। या बस हम कह सकते हैं:

The scope of cd command is only for child process not parent


2
यह करने के लिए जोड़ा जा रहा है,, प्रभाव आप देख रहे हैं प्राप्त करने के लिए @alex स्क्रिप्ट को निष्पादित भीतर यह सोर्सिंग द्वारा माता-पिता की प्रक्रिया: या तो . pathABCया source pathABC
zwets

4

आप एक सोच त्रुटि कर रहे हैं। जबकि वर्तमान शेल उसी निर्देशिका में रहता है, स्क्रिप्ट नई निर्देशिका में चली गई है।

आप देख सकते हैं कि नई निर्देशिका में एक और स्क्रिप्ट बनाकर और इसे अपनी स्क्रिप्ट से चलाने के बाद, यह निर्देशिका बदल गई है:

#!/bin/sh
cd /home/alex/Documents/A/B/C && ./another_script.sh # (if it is executable)

दूसरी स्क्रिप्ट नई निर्देशिका से चलेगी।

HelloWorld 

सिर्फ स्क्रिप्ट का आउटपुट है।


3
HelloWorld को मूल शेल में "वापस" नहीं किया गया है, यह मानक आउटपुट पर आउटपुट है
मोग

यदि आप pwdनई निर्देशिका में भाग लेते हैं , तो स्थिति के लिए पूरी नई स्क्रिप्ट जोड़ने के बजाय स्पष्ट हो सकती है।
वेजेंड्रिया

0

क्योंकि हैलो वर्ल्ड सिर्फ एक ट्रेस स्टेटमेंट है, आइए इसे आजमाते हैं:

बैश स्क्रिप्ट फ़ाइल बनाएँ cd.sh:

#!/bin/bash
echo "/home/mike/Documents/A/B/C"
  • .shविस्तार बैश स्क्रिप्ट देने के एक पुराने सम्मेलन एक विस्तार बदल दें है। यह पूरी तरह से कॉस्मेटिक है और आमतौर पर अनावश्यक है। हालांकि इस मामले में कोर cdकमांड से अंतर करना महत्वपूर्ण है ।

का उपयोग करके bash स्क्रिप्ट फ़ाइल निष्पादन योग्य को चिह्नित करें:

chmod a+x cd.sh

अब फ़ाइल चलाएँ:

$ cd $(./cd.sh)
bash: cd: /home/alex/Documents/A/B/C: No such file or directory
  • cd हम सभी को मालूम है।
  • $(...) कोष्ठक के अंदर कमांड निष्पादित करता है और आउटपुट देता है।
  • यदि cd.shआपके रास्ते में था तो आपको यह निर्दिष्ट करने की आवश्यकता नहीं है कि यह कहाँ है। हम ./कमांड को वर्तमान निर्देशिका में निर्दिष्ट करने के लिए उपसर्ग करते हैं।
  • echoसे उत्पादन cd.shस्क्रिप्ट के माध्यम से माता-पिता के लिए वापस भेज दिया जाता है $(...)। मूल (हमारा शेल प्रॉम्प्ट) इस आउटपुट का उपयोग करता है और इसे लिनक्स cdकमांड में भेजता है।

जैसा कि दूसरों ने उल्लेख किया है कि एक बच्चे की प्रक्रिया माता-पिता की निर्देशिका को बदल नहीं सकती है। यह एक तरीका है जिससे बच्चा माता-पिता को बता सकता है कि प्रक्रिया समाप्त होने के बाद कहां जाना है।


@wjandrea यही आपको फोन पर कोडिंग के लिए मिलता है! अभी घर आया हूँ, ठीक कर दूँगा। धन्यवाद। उम सिर्फ जाँच की और यह ठीक काम करता है। शायद यह आपका 14.04संस्करण है जिसे मैंने एक घंटे पहले पढ़ा है?
विनयुनुच्स 2 यूनिक्स

खैर, आपने स्क्रिप्ट पूरी तरह से बदल दी। पहले यह सिर्फ एक कमांड था: cd /home/mike/Documents/A/B/Cजो कोई आउटपुट नहीं देता था। अब यह echo "/home/mike/Documents/A/B/C"उत्पादन का उत्पादन करता है।
११:०१ बजे जूलरी

@wjandrea सच, मैंने स्क्रिप्ट को कॉल करने के तरीके को भी पूरी तरह से बदल दिया है। एक साधारण के बजाय ./cd.shयह अब है cd $(./cd.sh)लेकिन यह माता-पिता की वर्तमान निर्देशिका को बदलने वाले बच्चे के लक्ष्य को पूरा करता है। हां यह अपरंपरागत है लेकिन यह ऐसा करने का एक और तरीका है जिससे मुझे उम्मीद है कि लोग दिलचस्प पाएंगे।
WinEunuuchs2Unix
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.