Perché l'uso di due comandi cd nello script bash non esegue il secondo comando?


15

Ho scritto uno script bash che crea una serie di directory e clona un progetto in directory selezionate.

Per questo, ho bisogno di cdogni directory ( project 1e project 2), ma lo script non va cdnella seconda directory né esegue il comando.

Invece, si interrompe dopo cde la clonazione nella project2directory. Perché non chiama la cd_project1funzione nel seguente codice?

#!/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

Uscita terminale:

~/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
Prendi in considerazione l'idea di accettare una delle risposte. Se più di una risposta è una soluzione a una domanda, accetta la migliore e vota un'altra.
LeonidMew,

1
Ciao LeonidMew. Scusa, non ho idea di come accettare le risposte. Entrambe le risposte sono ugualmente buone però.
Jenny

5
@Jenny, non sentirti affrettata. Leggi Cosa devo fare quando qualcuno risponde alla mia domanda? invece e agisci di conseguenza quando sei soddisfatto . Prenditi il ​​tuo tempo, non c'è motivo di sbrigarsi. È perfettamente OK se decidi in un giorno o in una settimana o in qualsiasi momento.
PerlDuck,

2
@LeonidMew Sono passati appena 45 minuti da quando è stata posta la domanda, aspettare più a lungo è A-OK, potrebbe anche arrivare una risposta migliore (come dice il commento di PerlDuck, è saltata fuori mentre stavo scrivendo)
Xen2050

6
Sono curioso di sapere cosa intendevi exec bashfare.
In pausa fino a ulteriore avviso.

Risposte:


28

I colpevoli sono le tue exec bashdichiarazioni in alcune delle tue funzioni. L' execaffermazione è un po 'strana e non facilmente comprensibile in primo luogo. Significa: eseguire il comando seguente anziché il comando / shell / script attualmente in esecuzione da qui in poi . Cioè: sostituisce l'attuale script di shell (nel tuo caso) con un'istanza di bashe non ritorna mai.

Puoi provarlo con una shell e un problema

exec sleep 5

Questo sostituirà la tua shell corrente (la bash) con il comando sleep 5 e quando quel comando ritorna (dopo 5 secondi) la tua finestra si chiuderà perché la shell è stata sostituita con sleep 5.

Lo stesso con lo script: se lo inserisci exec somethingnello script, lo script viene sostituito con somethinge quando ciò somethinginterrompe l'esecuzione, l'intero script si interrompe.

exec bashDovrebbe semplicemente cadere le dichiarazioni.


2
@Jenny Bello da ascoltare. Aneddoto: Il linguaggio Perl ha anche una execdichiarazione con lo stesso comportamento e se si mette alcune dichiarazioni dopo una execdichiarazione (come exec something; print "This won't run";), allora il Perl vi avvertirà che la printdichiarazione non sarà mai eseguito.
PerlDuck,

9
BTW si congratula per l'uso di && after cd, (se non lo usi set -e). Ho visto Code like cd tmp; rm -rf *fail horrible
eckes

15

Da 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.

La parola chiave qui è sostituisci : se exec bashdall'interno di uno script, non può verificarsi alcuna ulteriore esecuzione dello script.


0

se vuoi tornare alla directory che hai iniziato potresti usare

cd -

Ma se non sei sicuro che un cdcomando sia stato eseguito, sarebbe meglio usare i comandi per mettere le directory di lavoro in uno stack:

pushd

e tornare ad esso (anche dopo più modifiche alla directory)

popd

assicurati di avere pari pushde popdcomandi.


2
Non sono sicuro che tu abbia letto o compreso lo spazio del problema. Nessuno di questi comandi aiuterà l'utente.
pipe

Da nessuna parte posso leggere la necessità di eseguire alcuni comandi in una shell. Quindi ho pensato che avesse chiamato bash per tornare nella directory di avvio. Se insisti, potresti dire: ha chiesto il motivo della continuazione mancante, alla quale si rispondono perfettamente le altre risposte.
Bernd Wilke πφ il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.