Pourquoi "cd" ne fonctionne-t-il pas dans un script shell?

37

Je veux juste écrire un script qui change mon répertoire .

Je mets les commandes ci-dessous dans le fichier /home/alex/pathABC

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

J'ai fait chmod +x pathABC .

Dans le terminal, alors que dans /home/alex , j'exécute ./pathABC , mais la sortie est juste HelloWorld et le répertoire actuel n'est pas modifié.

Alors, qu'est-ce qui ne va pas?

    
posée Mohammad Reza Rezwani 11.06.2014 - 10:35
la source

4 réponses

69

Comme d’autres l’ont expliqué, le répertoire est modifié dans le processus fils de votre script, et non dans le processus terminal à partir duquel le script est appelé. Après la mort du processus enfant, vous êtes de retour dans le terminal qui est resté là où il se trouvait.

Plusieurs alternatives:

1. Lien symbolique

Placez un lien symbolique dans votre maison sur le long chemin d'accès auquel vous souhaitez accéder facilement

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

puis accédez au répertoire avec:

$ cd ~/pathABC

2. Alias ​​

Mettez un alias dans votre ~ / .bashrc:

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

( cliquez ici )

3. Fonction

Créez une fonction qui modifie le répertoire, la fonction s'exécute dans le processus de votre terminal et peut ensuite modifier son répertoire.

( ici )

4. Évitez de courir comme un enfant

Source de votre script au lieu de l'exécuter. Le sourcing (effectué par . ou source ) provoque l'exécution du script dans le même shell au lieu de s'exécuter dans son propre sous-shell.

$ . ./pathABC

( cliquez ici et ici )

5. cd-vars

Définissez l’option cdable_vars dans votre ~/.bashrc et créez une variable d’environnement dans le répertoire:

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

Ensuite, vous pouvez utiliser cd pathABC

( ici )

    
réponse donnée Gauthier 11.06.2014 - 11:33
la source
7

Lorsque vous exécutez un script dans un terminal, un processus enfant est exécuté. Dans ce programme enfant, c’est-à-dire que votre script changera selon le répertoire spécifié. Mais dans le processus parent, c’est-à-dire où vous exécutez, le script est toujours dans l’ancien chemin. OU simplement nous pouvons dire:

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

    
réponse donnée Tingrammer 11.06.2014 - 10:56
la source
4

Vous faites une erreur de réflexion. Alors que le shell actuel reste dans le même répertoire, le script a été déplacé dans le nouveau répertoire.

Vous pouvez le voir en créant un autre script dans le répertoire new et en l'exécutant à partir de votre script après avoir modifié le répertoire:

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

Le deuxième script serait exécuté à partir du nouveau répertoire.

HelloWorld 

n'est que la sortie du script.

    
réponse donnée Jacob Vlijm 11.06.2014 - 10:48
la source
0

Parce que bonjour monde est juste une instruction de trace, essayons ceci:

Créer un fichier de script bash cd.sh contenant:

#!/bin/bash
echo "/home/mike/Documents/A/B/C"
  • L'extension .sh est une ancienne convention consistant à attribuer aux noms de fichiers script bash une extension. C'est purement cosmétique et généralement inutile. Cependant, dans ce cas, il est important de différencier la commande core cd .

Marquez le fichier script exécutable bash en utilisant:

chmod a+x cd.sh

Exécutez maintenant le fichier:

$ cd $(./cd.sh)
bash: cd: /home/alex/Documents/A/B/C: No such file or directory
  • cd nous savons tous.
  • $(...) exécute la commande entre parenthèses et renvoie la sortie.
  • Si cd.sh était dans votre chemin, vous n'avez pas besoin de spécifier où il se trouve. Nous préfixons ./ pour spécifier que la commande est dans le répertoire en cours.
  • La sortie echo du script cd.sh est renvoyée au parent via $(...) . Le parent (notre invite shell) utilise cette sortie et la transmet à la commande Linux cd .

Comme d’autres l’ont mentionné, un processus enfant ne peut pas modifier le répertoire du parent. C'est un moyen par lequel l'enfant peut dire au parent où aller après la fin du processus.

    
réponse donnée WinEunuuchs2Unix 25.07.2018 - 00:08
la source

Lire d'autres questions sur les étiquettes