2017-10-01 7 views
1

J'ai créé un cli qui calcule l'emplacement d'un certain répertoire, et j'aimerais vraiment que le script change. Ma première approche était ./myscript | cd, que j'ai apprise ne fonctionne pas comme 1. cd ne prend pas les arguments redirigés, et 2. le script ne sera pas autorisé à changer le répertoire du shell parent.Pourquoi ma fonction shell ne peut-elle pas changer de répertoire à partir d'une entrée canalisée?

j'ai appris qu'il ya des solutions de contournement, et j'ai essayé de créer une fonction .bash_profile:

function cdir(){ 
    DIR="" 
    while read LINE; do 
     DIR=$LINE 
    done 
    echo $DIR 
    cd $DIR 
} 

maintenant en cours d'exécution ./myscript | cdir le bon répertoire est sortie, cependant, le répertoire est toujours pas changé. L'utilisation de la substitution de commande fonctionne: cd $(./myscript), mais je préférerais vraiment pouvoir écrire ceci en utilisant pipe. Avez-vous une idée de ce que je peux faire pour que cela fonctionne, ou au moins expliquez pourquoi ce n'est pas possible?

+2

Si vous exécutez 'pwd' à la fin de votre fonction, vous verrez que le répertoire * a été * modifié dans sa portée. Que cette portée corresponde à la portée parent dans un pipeline non spécifié par POSIX et varie de shell à shell (et entre différentes configurations d'exécution pour un shell spécifique - il est possible d'exécuter le dernier élément de pipeline dans le parent dans les nouvelles versions de bash , mais seulement si vous désactivez le support du contrôle de travail). –

Répondre

3

cd modifie le répertoire de travail en cours, qui est un attribut du processus. Lorsque vous utilisez un pipeline, shell crée un sous-processus et l'effet de cd (à l'intérieur de votre fonction) est perdu lorsque le sous-processus se termine.

cd -- "$(./myscript)" 

est la bonne façon de le faire. Ici, cd s'exécute dans votre shell actuel.


Voir aussi:

+1

Quibble - 'cd -" $ (./ myscript) "' est sans doute un peu plus correct. –

+1

Merci! Ainsi, la tuyauterie proprement dite engendre un nouveau processus. –