web-dev-qa-db-fra.com

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

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 je suis dans /home/alex, j’exécute ./pathABC, mais la sortie est simplement HelloWorld et le répertoire actuel n’a pas été modifié.

Alors qu'est-ce qui ne va pas?

41

Comme d'autres l'ont expliqué, le répertoire est modifié dans le processus enfant de votre script et non dans le processus terminal à partir duquel le script est appelé. Une fois que le processus enfant est mort, vous êtes de retour dans le terminal qui est laissé où il était.

Plusieurs alternatives:

1. Lien symbolique

Mettez un lien symbolique dans votre maison vers le long chemin 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"

(de 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 changer de répertoire.

(de ici )

4. Évitez de courir comme un enfant

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

$ . ./pathABC

(de ici et ici )

5. cd -able 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

(de ici )

72
Gauthier

Lorsque vous exécutez un script dans un terminal, un processus enfant s'exécute. Dans ce programme enfant, votre script passera dans le répertoire spécifié. Mais dans le processus parent, c’est-à-dire que vous exécutez le script est toujours dans l’ancien chemin. OR nous pouvons simplement dire:

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

7
Tingrammer

Vous faites une erreur de pensée. Bien que le Shell actuel reste dans le même répertoire, le script a été déplacé vers le nouveau répertoire.

Vous pouvez le constater en créant un autre script dans le répertoire nouvea et en l'exécutant à partir de votre script, une fois qu'il a changé de répertoire:

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

Le second script serait exécuté à partir du nouveau répertoire.

HelloWorld 

est juste la sortie du script.

4
Jacob Vlijm

Parce que hello world est juste une déclaration de trace, essayons ceci:

Créez le fichier de script bash cd.sh contenant:

#!/bin/bash
echo "/home/mike/Documents/A/B/C"
  • L'extension .sh est une convention plus ancienne qui consiste à donner une extension aux noms de fichiers de script bash. C'est purement esthétique et généralement inutile. Cependant, dans ce cas, il est important de faire la différence avec la commande principale cdname__.

Marquez le fichier de script bash comme exécutable en utilisant:

chmod a+x cd.sh

Maintenant, lancez le fichier:

$ cd $(./cd.sh)
bash: cd: /home/alex/Documents/A/B/C: No such file or directory
  • cdnous le 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 avec ./ pour spécifier que la commande est dans le répertoire en cours.
  • La sortie echodu script cd.sh est renvoyée au parent via la $(...). Le parent (notre invite Shell) utilise cette sortie et le transmet à la commande Linux cdname__.

Comme d'autres l'ont mentionné, un processus enfant ne peut pas changer le répertoire du parent. C'est une façon pour l'enfant de dire au parent où aller après la fin du processus.

0
WinEunuuchs2Unix