Utilisation sudo avec venv Raspberry

Bonjour,

Lorsque que je crée un virtualenv sur vscode sur Raspberry et que j'exécute mon code avec
sudo
, mon venv est ignoré.

Sur mon PC, je n'ai pas ce problème, mon venv est utilisé même avec
sudo
.

J'arrive à forcer l'utilisation du python de mon venv en indiquant le chemin mais pas pour autant l'ensemble de librairies qui le compose.

D'après les recherches que j'ai faites, cela serait une histoire
$PATH
qui est différent lorsque l'on utilise
sudo
.

Mon but serait de modifier ce
PATH
de sudo automatiquement comme sur mon PC mais pour ma Raspberry.

Il faudrait que je modifie le "Sudoers File" pour pouvoir faire cela :
(.venv) $ sudo -E env PATH=$PATH ./myscript.py


Auriez-vous une idée de comment faire ?

Merci d'avance.
Configuration: Linux / Firefox 92.0

5 réponses

  1. Modérateur
    Bonjour,

    Le
    PATH
    n'est pas modifié avec
    sudo
    , comme le montrent :
    echo $PATH
    sudo echo $PATH

    Par contre il est possible que ton venv altère tes variables d'environnement.

    Je t'invite également à clarifier l'erreur (contenu du venv, erreur python, etc...). Si python ne parvient pas à importer un module, contrôle la valeur de
    sys.path
    et vérifie que c'est cohérent. Vérifie également que les modules que tu ne parviens pas à importer on été correctement installés dans ton venv.

    Quoi qu'il en soit, n'étant pas très fan des venv (duplique plein de choses, force à mettre à jour plusieurs environnement, etc) donc ma recommandation serait de n'en utiliser qu'en cas de besoins réels (e.g. sur une machine en production).

    Si tu veux quand même utiliser des venv, je pense que cette discussion et celle-ci peuvent te débloquer.

    Bonne chance
    1. Merci pour la réponse,

      J'ai fait sans le venv et apparemment avec sudo, le chemin des librairies est modifié et au lieu d'aller dans usr, il va dans root. Pour utiliser sudo, je dois donc installer mes librairies avec sudo pip ce qui n'est pas très conseillé de ce que j'ai lu.
      1. Modérateur
        Bonjour,

        Il y a quelque chose que je ne comprends pas et j'aimerais être sûr qu'on se comprend. Tu parles de chemin de librairies, parles-tu de
        $LD_LIBRARY_PATH
        (au sens shellà, ou parles-tu des chemins vers les modules python, donc
        sys.path
        (au sens python). Ce sont deux choses indépendantes.

        Pour utiliser sudo, je dois donc installer mes librairies avec sudo pip ce qui n'est pas très conseillé de ce que j'ai lu.

        Je ne sais pas où tu as lu ça, mais c'est faux. Si tu utilises
        sudo
        (ou installe en root) un module python, il sera déployé dans
        /usr/local/lib
        au lieu d'être installé dans ton home. Cela signifie que tous les utilisateurs sur ta machine peuvent en bénéficier, ce qui est plutôt souhaitable. À cela j'ajouterai que certains paquets
        python3-...
        lancent moralement en arrière boutique un
        pip3 install
        (avec des droits root).

        Moi, j'ai plutôt l'avis inverse : je déconseille d'utiliser
        pip3
        en utilisateur, car du coup on se retrouve à jongler entre les modules pip3 installés en root, ceux installés en utilisateur et ceux installés avec
        apt
        (sans
        pip3
        ). Ma recommandation serait :
        • Installe autant que possible tes modules via
          apt
          : ils sont tous préfixés
          python3-...
          pour du python3 et
          python-...
          pour du python2. Note en particulier que les modules python2 (resp python3) ne sont pas compatibles avec python3 (resp. python2).
        • Si le module n'est pas disponible via
          apt
          , passe par
          sudo pip3
          par défaut (
          sudo pip
          pour python2) après avoir installé
          pip3
          via
          sudo apt install python3-pip
          (resp.
          sudo apt install python-pip
          pour python2).
        • Si le module n'est pas non plus disponible via
          pip3
          /
          pip
          , récupère les sources du modules, installe via
          apt
          le paquet
          python3-setuptools
          (resp.
          python-setuptools
          ) et installe-le avec
          sudo python3 setup.py install
          (resp.
          sudo python setup.py install
          ). Note qu'ici aussi je recommande d'utiliser
          sudo
          pour les mêmes raisons que celles que j'ai données pour
          pip3
          /
          pip
          . Il faut d'ailleurs souligner c'est ce fameux
          setup.py
          que
          pip3
          /
          pip
          finissent par lancer.


        Tu l'auras compris, je n'aime pas les venv pour les mêmes raisons. Je ne nie pas l'intérêt des venv pour une machine en production et pour laquelle on ne veut pas casser un service au cours d'une mise à jour. Mais c'est un besoin particulier et bien souvent, les mises à jours ne cassent rien. Les venv tendent juste à réinstaller une grosse partie de python dans chaque venv au détriment de l'espace disque et de la simplicité de maintenance.

        Si tu souhaites utiliser un venv, pas de problème mais dans ce cas, il faut clarifier les différentes erreurs (en copiant collant le message d'erreur exact) et indiquer précisément ce que tu appelles "chemin vers les librairies", de quelles librairies tu parles, et où elles sont installées. Sans ces informations, difficile pour moi de te guider.

        Bonne chance
        1. Merci pour cette réponse complète.

          Par librairies j'entends module (numpy, pandas...). Si j'ai bien compris utiliser sudo modifie le chemin d'accès de ces modules c'est pour cela que quand j'utilise sudo -E ça fonctionne car il va dans mon home au lieu d'aller dans /user/local/lib. Je n'ai pas touché à $LD_LIBRARY_PATH donc je te dirais que c'est dans le sens sys.path.

          Un peu flou, il y a un environnement de variables python et un environnement shell ?

          Par contre utiliser sudo pip3, signifie que je dois à chaque fois exécuter mon code avec sudo ?
          1. Modérateur
            Bonjour,

            Librairie ou module (python) ?

            Par librairies j'entends module (numpy, pandas...).

            Dans ce cas, parle bien de modules pythons (fichiers textes
            .py
            localisés dans
            /usr/lib/python...
            pour les installations via
            apt
            et
            /usr/local/lib/python...
            pour les installations via
            pip3
            ), à ne pas confondre avec des librairies (fichiers binaires
            .so
            ou
            .a
            localisés dans
            /usr/lib
            ou
            /lib
            ).

            Il est important de bien distinguer les deux.
            • Les modules pythons sont recherchés par l'interpréteur python (e.g.
              python3
              ) conformément à la valeur de
              sys.path
              (que tu peux altérer avant de faire un
              import
              ou mieux, compléter si ton module python est proprement installé avec
              python3 setup.py install
              -- c'est ce que fait
              pip3
              en arrière boutique).
            • Les librairies sont recherchées par l'OS (Operating System) au moment de charger un exécutables (tu peux d'ailleurs voir à quelles libraires un exécutable est lié avec la commande
              ldd
              , e.g.
              ldd $(which python3)
              . L'OS cherche ses librairies conformément à la variable d'environnement
              $LD_LIBRARY_PATH
              .


            Tu l'auras compris, la découverte des modules python ne dépend ni de ton shell, ni de ses variables d'environnement (et donc pas de
            $LD_LIBRARY_PATH
            ), mais uniquement de
            sys.path
            .

            Quelques vérifications préalables

            Une autre point intéressant serait de vérifier si tu lances dans les deux cas le même interpréteur python. Quand tu lances
            python3
            ton shell cherche au préalable (conformément à la variable d'environnement
            $PATH
            ) un dossier qui contient un exécutable qui porte ce nom. On peut voir le résultat de cette recherche avec la commande
            which python3
            (que j'ai déjà lâché un peu plus haut), et qui retournera par exemple
            /usr/bin/python3
            . Il serait intéressant de voir si tu obtiens le même résultat avec et sans
            sudo
            .

            which python3
            sudo which python3


            Tu peux aussi utiliser
            whereis python3
            qui listera les différentes possibilités que ton shell peut trouver.

            Ensuite, tu peux écrire un petit programme python qui affiche
            sys.path
            et que tu lances tantôt avec ton utilisateur, tantôt avec
            sudo
            .

            Exemple : Créons un fichier python, disons
            toto.py
            :

            #!/usr/bin/env python3
            import sys
            print(sys.path)


            Puis on compare :

            python3 toto.py
            sudo python3 toto.py


            Si tu observes des différences, c'est probablement que certains bouts (tes modules, ton interpréteur, ou les deux) sont installés dans ton dossier personnel (e.g.
            /home/toto
            ), et que
            sudo
            se place dans des conditions différentes (cf
            $PATH
            et la valeur de
            sys.path
            ).

            Pour finir...

            Si à l'issue de tout ceci, tu ne comprends toujours pas le problème, je t'invite à me reporter les valeur de
            $PATH
            ,
            sys.path
            , le module python que tu tentes de charger et le dossier dans lequel il est installé.

            Bonne chance