web-dev-qa-db-fra.com

Python - Activer la conda env via le script Shell

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'.
17
user9074332

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.

9
Niayesh Isky

J'utilise la 'commande source' pour exécuter le script Shell, cela fonctionne:

source Shell_script.sh
9
qidong

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.

Explication

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.

Références

5
Simba

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.

1
Lamma

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).

0
HAltos