बैश स्क्रिप्ट में दो cd कमांड का इस्तेमाल क्यों नहीं किया जाता है?


15

मैंने एक बैश स्क्रिप्ट लिखी है जो निर्देशिकाओं की एक श्रृंखला बनाता है और चयनित निर्देशिकाओं के लिए एक क्लोन क्लोन करता है।

उसके लिए, मुझे cdप्रत्येक निर्देशिका ( project 1और project 2) की आवश्यकता है, लेकिन स्क्रिप्ट cdदूसरी निर्देशिका में नहीं है और न ही कमांड निष्पादित करती है।

इसके बजाय, यह निर्देशिका cdमें क्लोनिंग और उसके बाद बंद हो जाता है project2। यह cd_project1निम्नलिखित कोड में फ़ंक्शन को क्यों नहीं बुलाता है ?

#!/bin/bash
#Get the current user name 

function my_user_name() {        
current_user=$USER
echo " Current user is $current_user"
}

#Creating useful directories

function create_useful_directories() {  
  if [[ ! -d "$scratch" ]]; then
  echo "creating relevant directory"
  mkdir -p /home/"$current_user"/Downloads/scratch/"$current_user"/project1/project2
  else
     echo "scratch directory already exists"
     :
  fi
}

#Going to project2 and cloning 

function cd_project2() {

  cd /home/"$current_user"/Downloads/scratch/"$current_user"/project1/project2 &&
  git clone https://username@bitbucket.org/teamsinspace/documentation-tests.git
  exec bash
}

#Going to project1 directory and cloning 
function cd_project1() {

  cd /home/"$current_user"/Downloads/scratch/"$current_user"/project1/ &&
  git clone https://username@bitbucket.org/teamsinspace/documentation-tests.git
  exec bash

}

#Running the functions  
function main() {

  my_user_name
  create_useful_directories
  cd_project2
  cd_project1    
}
main

टर्मिनल आउटपुट:

~/Downloads$. ./bash_install_script.sh    
Current user is mihi
creating relevant directory
Cloning into 'documentation-tests'...
remote: Counting objects: 125, done.
remote: Compressing objects: 100% (115/115), done.
remote: Total 125 (delta 59), reused 0 (delta 0)
Receiving objects: 100% (125/125), 33.61 KiB | 362.00 KiB/s, done.
Resolving deltas: 100% (59/59), done.
~/Downloads/scratch/mihi/project1/project2$

3
किसी एक उत्तर को स्वीकार करने पर विचार करें। यदि एक से अधिक उत्तर एक प्रश्न का हल है - तो सबसे अच्छा एक को स्वीकार करें और दूसरे को वोट दें।
लियोनिडेम्यू

1
हाय लियोनिडम्यू। क्षमा करें, मुझे नहीं पता कि उत्तरों को कैसे स्वीकार किया जाए। हालांकि दोनों उत्तर समान रूप से अच्छे हैं।
22

5
@ जेनी, जल्दी मत करो। पढ़ें मैं जब कोई मेरे सवाल का जवाब क्या करना चाहिए? इसके बजाय और जब आप संतुष्ट हों उसी के अनुसार कार्य करें । बस अपना समय ले लो, जल्दी करने का कोई कारण नहीं है। यह पूरी तरह से ठीक है यदि आप एक दिन में या एक सप्ताह में या जो भी समय लगता है, उसमें निर्णय लेते हैं।
PerlDuck

2
@LeonidMew यह सवाल पूछे जाने के बाद से मुश्किल से 45 मिनट का है, प्रतीक्षा में ए-ओके है, एक बेहतर जवाब भी साथ आ सकता है (जैसे कि पर्लडक की टिप्पणी कहती है, यह सिर्फ टाइप करते समय पॉप अप हो गया)
Xen20x

6
मैं उत्सुक हूं कि आपने क्या करने का इरादा exec bashकिया है।
अगली सूचना तक रोक दिया गया।

जवाबों:


28

आपके exec bashकुछ कार्यों में अपराधी आपके बयान हैं । execबयान थोड़ा अजीब और आसानी से पहली जगह में नहीं समझा जा सका है। इसका अर्थ है: यहां से वर्तमान में चल रहे कमांड / शेल / स्क्रिप्ट के बजाय निम्नलिखित कमांड निष्पादित करें । वह यह है: यह वर्तमान शेल स्क्रिप्ट (आपके मामले में) की एक आवृत्ति के साथ बदलता है bashऔर यह कभी नहीं लौटता है।

आप इसे खोल और मुद्दे के साथ आज़मा सकते हैं

exec sleep 5

यह आपके वर्तमान शेल ( bash) को कमांड के साथ बदल देगा sleep 5 और जब वह कमांड वापस आएगा (5 सेकंड के बाद) तो आपकी विंडो बंद हो जाएगी क्योंकि शेल को बदल दिया गया है sleep 5

आपकी स्क्रिप्ट के साथ भी: यदि आप exec somethingअपनी स्क्रिप्ट में डालते हैं , तो स्क्रिप्ट को बदल दिया जाता है somethingऔर जब somethingनिष्पादन बंद हो जाता है, तो पूरी स्क्रिप्ट बंद हो जाती है।

बस exec bashबयानों को छोड़ देना चाहिए।


2
@ जेनी सुनकर अच्छा लगा। किस्सा: पर्ल लैंग्वेज में भी execउसी व्यवहार के साथ एक स्टेटमेंट होता है और यदि आप किसी स्टेटमेंट (जैसे ) के बाद कुछ स्टेटमेंट डालते हैं तो पर्ल आपको चेतावनी देगा कि स्टेटमेंट कभी एक्सेप्ट नहीं होगा। execexec something; print "This won't run";print
पर्लडक

9
BTW सीडी के बाद && का उपयोग करने पर बधाई देता है, (यदि आप उपयोग नहीं करते हैं set -e)। मैंने कोड को cd tmp; rm -rf *असफल भयानक की तरह देखा है
19

15

से help exec:

exec: exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
    Replace the shell with the given command.

    Execute COMMAND, replacing this shell with the specified program.
    ARGUMENTS become the arguments to COMMAND.  If COMMAND is not specified,
    any redirections take effect in the current shell.

यहाँ कुंजी शब्द प्रतिस्थापित किया गया है - यदि आप exec bashकिसी स्क्रिप्ट के अंदर से हैं, तो आगे कोई स्क्रिप्ट निष्पादन नहीं हो सकता है।


0

यदि आप उस निर्देशिका पर वापस जाना चाहते हैं जिसे आपने शुरू किया था तो आप उसका उपयोग कर सकते हैं

cd -

लेकिन अगर आप सुनिश्चित नहीं हैं कि एक cdकमांड को बिल्कुल निष्पादित किया गया है, तो वर्किंग डायरेक्टरीज़ को स्टैक पर रखने के लिए कमांड्स का उपयोग करना बेहतर होगा:

pushd

और उस पर लौटें (भले ही कई निर्देशिकाओं में बदलाव के बाद)

popd

बराबरी pushdऔर popdआज्ञा सुनिश्चित करें ।


2
मुझे यकीन नहीं है कि आपने समस्या स्थान को पढ़ा या समझा है। इनमें से कोई भी आदेश उपयोगकर्ता की मदद नहीं करेगा।
पाइप

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