2009-09-14 6 views
30

Je dois autoriser plusieurs applications à ajouter à une variable système ($ PYTHONPATH dans ce cas). Je pense à désigner un répertoire où chaque application peut ajouter un module (par exemple .bash_profile_modulename). J'ai essayé quelque chose comme ça dans ~/.bash_profile:source tous les fichiers dans un répertoire de .bash_profile

find /home/mike/ -name ".bash_profile_*" | while read FILE; do 
source "$FILE" 
done; 

mais cela ne semble pas fonctionner.

+1

Un script de test rapide fonctionne pour moi. Pouvez-vous être plus précis quant à ce que vos fichiers contiennent et ce que «ne semble pas fonctionner» signifie? –

+0

Les fichiers ressemblent à: export PYTHONPATH =/testpath /: $ PYTHONPATH Le problème est qu'il n'ajoute pas/testpath/au PYTHONPATH. –

+3

Juste pour expliquer pourquoi le script original ne fonctionne pas: les fichiers proviennent d'une boucle while dans un pipeline; Les builtins bash utilisés dans les pipelines s'exécutent dans des sous-cases, de sorte que tout ce qui est défini par les fichiers sources disparaît lorsque le sous-shell se ferme. La solution (comme dans les réponses ci-dessous) est d'éliminer le pipeline. –

Répondre

54

Ne serait-

for f in ~/.bash_profile_*; do source $f; done 

suffisant?

Édition: Couche supplémentaire de ls ~/.bash_* simplifiée pour la bascule directe.

+2

pour f dans ~/.bash_profile_ *; faire la source $ f; fait devrait fonctionner aussi; bash peut gérer le globbing. –

+1

Emil: Vous avez raison. Merci pour la suggestion. –

+0

Dirk, vous devriez éditer votre réponse avec la suggestion d'Emil. –

17

Je suis d'accord avec Dennis ci-dessus; votre solution devrait fonctionner (bien que le point-virgule après "done" ne soit pas nécessaire). Cependant, vous pouvez également utiliser une boucle

for f in /path/to/dir*; do 
    . $f 
done 

La substitution de commande de ls n'est pas nécessaire, comme dans la réponse de Dirk. C'est le mécanisme utilisé, par exemple, dans /etc/bash_completion pour trouver d'autres scripts d'achèvement de bash dans /etc/bash_completion.d

+1

Je crois que vous avez besoin de citations. '. "$ f" '. Autre que cela, la meilleure réponse. –

-1

ok donc ce que j'ai fini par faire;

eval "$(find perf-tests/ -type f -iname "*.test" | while read af; do echo "source $af"; done)" 

cette exécutera une source dans le shell courant et maintian toutes les variables ...

-3

Je pense que vous devriez juste être capable de faire

source ~/.bash_profile_*

+1

Je pensais la même chose, mais j'ai testé et je ne pouvais pas le faire fonctionner. Il me semble que 'source' ne prend qu'un argument (et ignore les arguments superflus). Je suis assez sûr que ce genre de craint. – bryn

2

aus man bash:

nom de fichier source [arguments]

ein config source/*

Le premier argument sera sourcé et tous les autres fichiers dans config/seront arguments au script, il sources.

8

Oneliner (uniquement pour bash/zsh):

source <(cat *) 
+1

Cela fonctionne aussi pour zsh. – fangxing

+0

Cela ne fonctionne pas pour Bash. Vous obtenez une erreur "nom": Est-ce un répertoire –

+0

@BalajiBoggaramRamanarayan de cause si vous avez des répertoires là-bas! La question concerne les fichiers. Trouvez un masque qui inclura uniquement les fichiers. – gaRex

0
for file in "$(find . -maxdepth 1 -name '*.sh' -print -quit)"; do source $file; done 

Cette solution est que j'ai trouvé le plus postable, jusqu'à présent: * Il ne donne aucune erreur s'il n'y a pas de fichiers correspondant à * travaille avec plusieurs obus, y compris bash, zsh * multi-plateforme (Linux, MacOS, ...)

0
str="$(find . -type f -name '*.sh' -print)" 
arr=($str) 
for f in "${arr[@]}"; do 
    [[ -f $f ]] && . $f --source-only || echo "$f not found" 
done 

Je l'ai testé et je l'utilise. Modifiez simplement le. après trouver pour pointer vers votre dossier avec vos scripts et cela fonctionnera.

Questions connexes