J'espère pouvoir exécuter un simple script Shell pour faciliter la gestion de certains environnements conda. Activation des environnements conda via conda activate
dans un linux
os fonctionne bien dans le Shell mais est problématique dans un script Shell. Quelqu'un pourrait-il m'indiquer dans la bonne direction pourquoi cela se produit?
Exemple pour répéter le problème:
# default conda env
$ conda info|egrep "conda version|active environment"
active environment : base
conda version : 4.6.9
# activate new env to prove that it works
$ conda activate scratch
$ conda info|egrep "conda version|active environment"
active environment : scratch
conda version : 4.6.9
# revert back to my original conda env
$ conda activate base
$ cat Shell_script.sh
#!/bin/bash
conda activate scratch
# run Shell script - this will produce an error even though it succeeded above
$ ./Shell_script.sh
CommandNotFoundError: Your Shell has not been properly configured to use 'conda activate'.
To initialize your Shell, run
$ conda init <Shell_NAME>
Currently supported shells are:
- bash
- fish
- tcsh
- xonsh
- zsh
- powershell
See 'conda init --help' for more information and options.
IMPORTANT: You may need to close and restart your Shell after running 'conda init'.
Le message d'erreur est plutôt utile - il vous indique que conda n'est pas correctement configuré à partir du sous-shell dans lequel votre script s'exécute. Pour pouvoir utiliser conda dans un script, vous devrez (comme le dit le message d'erreur) exécuter conda init bash
(Ou quel que soit votre Shell) en premier. Le comportement de conda et sa configuration dépendent de votre version de conda, mais la raison du comportement de la version 4.4+ est que conda
dépend de certaines variables d'environnement qui sont normalement configurées par le shell conda lui-même. Plus important encore, cette entrée du journal des modifications explique pourquoi vos commandes conda activate
Et deactivate
ne se comportent plus comme prévu dans les versions 4.4 et supérieures.
Pour plus de discussion à ce sujet, consultez le problème de conda officiel sur GitHub.
Edit: Quelques recherches supplémentaires me disent que la fonction conda init
Mentionnée dans le message d'erreur est en fait une nouvelle fonctionnalité v4.6.0 qui permet une configuration rapide de l'environnement afin que vous puissiez utiliser conda activate
Au lieu de l'ancienne source activate
. Cependant, la raison pour laquelle cela fonctionne est qu'il ajoute/modifie plusieurs variables d'environnement de votre shell actuel et apporte également des modifications à votre fichier RC (par exemple: .bashrc
), Et les modifications du fichier RC ne sont jamais récupérées dans le courant Coque - uniquement dans les coques nouvellement créées. (À moins bien sûr que vous n'achetiez à nouveau .bashrc). En fait, conda init --help
En dit autant:
IMPORTANT: après avoir exécuté
conda init
, La plupart des shells devront être fermés et redémarrés pour que les modifications prennent effet
Cependant, vous avez clairement déjà exécuté conda init
, Car vous êtes capable d'utiliser conda activate
De manière interactive. En fait, si vous ouvrez votre .bashrc, vous devriez pouvoir voir quelques lignes ajoutées par conda en apprenant à votre shell où chercher les commandes conda. Le problème avec votre script réside cependant dans le fait que le .bashrc n'est pas fourni par le sous-shell qui exécute les scripts Shell (voir cette réponse pour plus d'informations). Cela signifie que même si votre shell interactif sans connexion voit les commandes conda, vos sous-shell de script non interactifs ne le feront pas, peu importe le nombre de fois que vous appelez conda init
.
Cela conduit à une conjecture (je n'ai pas de conda sous Linux moi-même, donc je ne peux pas le tester) qu'en exécutant votre script comme ceci:
bash -i Shell_script.sh
vous devriez voir conda activate
fonctionner correctement. Pourquoi? -i
Est un indicateur bash qui indique au shell que vous commencez à exécuter en mode interactif, ce qui signifie qu'il source automatiquement votre .bashrc. Cela devrait être suffisant pour vous permettre d'utiliser conda dans votre script comme si vous l'utilisiez normalement.
J'utilise la 'commande source' pour exécuter le script Shell, cela fonctionne:
source Shell_script.sh
Solution rapide pour bash
: ajoutez le script d'initialisation suivant dans vos scripts Bash.
eval "$(command conda 'Shell.bash' 'hook' 2> /dev/null)"
Terminé.
Pour les autres shells, vérifiez l'init conf de votre Shell, copiez le contenu suivant dans la conf de Shell et ajoutez-le dans vos scripts.
# >>> conda initialize >>>
...
# <<< conda initialize <<<
Vous pouvez aussi utiliser
conda init --all --dry-run --verbose
pour obtenir le script init dont vous avez besoin dans vos scripts.
Ceci est lié à l'introduction de conda init
dans conda
4.6.
Citation du journal des versions de conda 4.6
Conda 4.4 autorisait "conda activate envname". Le problème était que la configuration de votre Shell pour utiliser cette nouvelle fonctionnalité n'était pas toujours simple. Conda 4.6 ajoute un support d'initialisation étendu afin que plus de shells que jamais puissent utiliser la nouvelle commande "conda activate". Pour plus d'informations, lisez la sortie de "conda init –help"
Après conda init
est introduit dans conda
4.6, conda expose uniquement la commande conda
dans le PATH
mais pas tous les binaires de "base". Et le changement d'environnement est unifié par conda activate env-name
et conda deactivate
sur toutes les plateformes.
Mais pour que ces nouvelles commandes fonctionnent, vous devez effectuer une initialisation supplémentaire avec conda init
.
Le problème est que votre fichier de script est exécuté dans un sous-shell et conda
n'est pas initialisé dans ce sous-shell.
L'utilisation de conda activate
Ou source activate
Dans les scripts Shell ne fonctionne pas toujours et peut générer une erreur comme celle-ci. Un travail simple pour placer source ~/miniconda3/etc/profile.d/conda.sh
Au-dessus de toute commande conda activate
Dans le script:
source ~/miniconda3/etc/profile.d/conda.sh
conda activate some-conda-environment
C'est la solution qui a fonctionné pour moi et fonctionnera également si vous partagez des scripts. Cela permet également d'éviter d'avoir à utiliser conda init
Car sur certains clusters avec lesquels j'ai travaillé, le système est initialisé mais conda activate
Ne fonctionnera toujours pas dans un script Shell.
Quel est le problème avec simplement faire quelque chose comme ça dans votre Shell:
source /opt/conda/etc/profile.d/conda.sh
(Le conda init est toujours marqué comme expérimental, et donc pas sûr que ce soit une bonne idée de l'utiliser encore).