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




shell (18)

मैं अपनी निर्देशिका निर्देशिका में वर्तमान निर्देशिका को बदलने के लिए एक छोटी लिपि लिखने की कोशिश कर रहा हूं:

#!/bin/bash
cd /home/tree/projects/java

मैंने इस फ़ाइल को proj के रूप में सहेजा, chmod साथ निष्पादन अनुमति जोड़ा, और इसे /usr/bin कॉपी किया। जब मैं इसे कहता हूं: proj , यह कुछ भी नहीं करता है। मैं क्या गलत कर रहा हूं?


अंत में exec bash प्रयोग करें

एक बैश स्क्रिप्ट अपने वर्तमान माहौल या उसके बच्चों पर संचालित होती है, लेकिन अपने मूल वातावरण पर कभी नहीं।

हालांकि, यह प्रश्न अक्सर पूछता है क्योंकि किसी अन्य निर्देशिका से बैश स्क्रिप्ट निष्पादित करने के बाद किसी निश्चित निर्देशिका में किसी बैश प्रॉम्प्ट पर छोड़ा जाना चाहता है।

यदि ऐसा है, तो स्क्रिप्ट के अंत में केवल एक बच्चे बैश उदाहरण निष्पादित करें:

#!/bin/bash
cd /home/tree/projects/java
exec bash

एक बैश स्क्रिप्ट बनाने के लिए जो एक सीडी निर्देशिका में सीडी होगा:

स्क्रिप्ट फ़ाइल बनाएं

#!/bin/sh
# file : /scripts/cdjava
#
cd /home/askgelal/projects/java

फिर अपनी स्टार्टअप फ़ाइल में उपनाम बनाएं।

#!/bin/sh
# file /scripts/mastercode.sh
#
alias cdjava='. /scripts/cdjava'
  • मैंने एक स्टार्टअप फ़ाइल बनाई जहां मैं अपने सभी उपनाम और कस्टम फ़ंक्शंस को डंप करता हूं।
  • फिर मैं इस बूट को अपने .bashrc में प्रत्येक बूट पर सेट करने के लिए स्रोत करता हूं।

उदाहरण के लिए, एक मास्टर उपनाम / फ़ंक्शंस फ़ाइल बनाएं: /scripts/mastercode.sh
(इस फाइल में उपनाम रखो।)

फिर आपके .bashrc फ़ाइल के अंत में:

source /scripts/mastercode.sh


अब अपनी जावा निर्देशिका में सीडी करना आसान है, बस cdjava टाइप करें और आप वहां हैं।


आप उपनाम और एक स्क्रिप्ट को जोड़ सकते हैं,

alias proj="cd \`/usr/bin/proj !*\`"

बशर्ते कि स्क्रिप्ट गंतव्य पथ को echos। ध्यान दें कि वे स्क्रिप्ट नाम के आस-पास की बैकटिक्स हैं।

उदाहरण के लिए, आपकी स्क्रिप्ट हो सकती है

#!/bin/bash
echo /home/askgelal/projects/java/$1

इस तकनीक के साथ लाभ यह है कि स्क्रिप्ट किसी भी कमांड लाइन पैरामीटर ले सकती है और संभवतः जटिल तर्क द्वारा गणना की गई विभिन्न गंतव्यों को उत्सर्जित कर सकती है।


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

स्क्रिप्ट

इसे निष्पादित करने के लिए, यह सबहेल में निष्पादित नहीं होगा।


आप ऑपरेटर का उपयोग कर सकते हैं &&:

सीडी myDirectory & ls


आप कुछ भी गलत नहीं कर रहे हैं! आपने निर्देशिका बदल दी है, लेकिन केवल स्क्रिप्ट चलाने वाले सबशेल के भीतर।

आप अपनी वर्तमान प्रक्रिया में स्क्रिप्ट को "डॉट" कमांड के साथ चला सकते हैं:

. proj

लेकिन मैं इस साधारण मामले में उपनाम का उपयोग करने के लिए ग्रेग के सुझाव को प्राथमिकता दूंगा।


आपकी ~ / .bash_profile फ़ाइल में। अगला फ़ंक्शन जोड़ें

move_me() {
    cd ~/path/to/dest
}

टर्मिनल पुनरारंभ करें और आप टाइप कर सकते हैं

move_me 

और आपको गंतव्य फ़ोल्डर में ले जाया जाएगा।


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

इस समस्या को हल करने के लिए एक Posix- संगत तरीका एक खोल-आवंटित कमांड स्क्रिप्ट के बजाय एक खोल प्रक्रिया को परिभाषित करना है।

jhome () {
  cd /home/tree/projects/java
}

आप इसे टाइप कर सकते हैं या इसे विभिन्न शैल स्टार्टअप फाइलों में से एक में डाल सकते हैं।


जब आप एक शेल स्क्रिप्ट को आग लगाते हैं, तो यह उस खोल का एक नया उदाहरण चलाता है ( /bin/bash )। इस प्रकार, आपकी स्क्रिप्ट सिर्फ एक खोल को फायर करती है, निर्देशिका बदलती है और बाहर निकलती है। एक और तरीका रखो, एक शेल स्क्रिप्ट के भीतर cd (और ऐसे अन्य आदेश) प्रभावित नहीं होते हैं और न ही उन्हें खोलने वाले खोल तक पहुंच प्राप्त होती है।


जिस स्क्रिप्ट को आप चलाने के लिए चाहते हैं उसे सोर्स करना एक समाधान है, आपको अवगत होना चाहिए कि यह स्क्रिप्ट तब आपके वर्तमान खोल के वातावरण को सीधे संशोधित कर सकती है। इसके अलावा अब तर्कों को पार करना संभव नहीं है।

करने का एक और तरीका है, अपनी स्क्रिप्ट को बैश में फ़ंक्शन के रूप में कार्यान्वित करना है।

function cdbm() {
  cd whereever_you_want_to_go
  echo "Arguments to the functions were $1, $2, ..."
}

इस तकनीक का उपयोग autojump द्वारा किया जाता है: http://github.com/joelthelion/autojump/wiki आपको शैल निर्देशिका बुकमार्क सीखने के साथ प्रदान करता है।



बस चलाएं:

cd /home/xxx/yyy && command_you_want

मुझे अपना कोड उपयोग करके काम करने के लिए मिला . <your file name> . <your file name>

./<your file name> खुराक काम नहीं करता है क्योंकि यह टर्मिनल में आपकी निर्देशिका नहीं बदलता है, यह सिर्फ उस स्क्रिप्ट के लिए विशिष्ट निर्देशिका को बदलता है।

मेरा कार्यक्रम यहाँ है

#!/bin/bash 
echo "Taking you to eclipse's workspace."
cd /Developer/Java/workspace

मेरा टर्मिनल यहाँ है

nova:~ Kael$ 
nova:~ Kael$ . workspace.sh
Taking you to eclipe's workspace.
nova:workspace Kael$ 

मेरे पास निर्देशिका को बदलने के प्रबंधन के लिए पी नामक एक साधारण बैश स्क्रिप्ट है
github.com/godzilla/bash-stuff
बस स्क्रिप्ट को अपनी स्थानीय बिन निर्देशिका में रखें (/ usr / local / bin)
और रखें

alias p='. p'

आपके .bashrc में


यदि आप अपने खोल के रूप में fish का उपयोग कर रहे हैं, तो सबसे अच्छा समाधान एक समारोह बनाना है। उदाहरण के तौर पर, मूल प्रश्न दिया गया है, आप नीचे दी गई 4 पंक्तियों की प्रतिलिपि बना सकते हैं और उन्हें अपनी मछली कमांड लाइन में पेस्ट कर सकते हैं:

function proj
   cd /home/tree/projects/java
end
funcsave proj

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

यदि आप चाहें, तो आप निम्न कार्य करके मैन्युअल रूप से फ़ंक्शन फ़ाइल जोड़ सकते हैं:

nano ~/.config/fish/functions/proj.fish

और पाठ दर्ज करें:

function proj
   cd /home/tree/projects/java
end

और अंत में बाहर निकलने के लिए ctrl + x दबाएं और y आपके परिवर्तनों को सहेजने के लिए वापस लौटें।

( नोट: funcsave का उपयोग करने की पहली विधि आपके लिए proj.fish फ़ाइल बनाता है )।


यदि आप बैकस्लैश के साथ लाइनें समाप्त करते हैं तो आप उसी सबहेल में कुछ पंक्तियां निष्पादित कर सकते हैं।

cd somedir; \
pwd

शेल स्क्रिप्ट एक सबहेल के अंदर चलाए जाते हैं, और प्रत्येक शख्सियत की अपनी अवधारणा होती है कि वर्तमान निर्देशिका क्या है। cd सफल होता है, लेकिन जैसे ही सबहेल निकलता है, आप इंटरैक्टिव शैल में वापस आ जाते हैं और वहां कभी भी कुछ भी नहीं बदला जाता है।

इसके आस-पास जाने का एक तरीका इसके बजाय उपनाम का उपयोग करना है:

alias proj="cd /home/tree/projects/java"

cd स्क्रिप्ट के खोल के भीतर किया जाता है। जब स्क्रिप्ट समाप्त होती है, वह खोल निकलता है, और तब आप उस निर्देशिका में छोड़े जाते हैं जो आप थे। स्क्रिप्ट "स्रोत", इसे चलाएं नहीं। के बजाय:

./myscript.sh

कर

. ./myscript.sh

(स्क्रिप्ट नाम से पहले डॉट और स्पेस पर ध्यान दें।)







shell