14 Stimmen

Warum werden Module im PYTHONPATH nicht gefunden, wenn das enthaltende Verzeichnis Teil des PYTHONPATH ist und die Datei vorhanden ist?

Ich habe folgende Situation (Überprüfung durch Befehle unten):

  • existierende Python-Skriptdatei im Verzeichnis x
  • existierende Python-Skriptdatei __init__.py in x
  • x hinzugefügt zur PYTHONPATH-Variable verfügbar für sowohl eingeloggten Benutzer als auch sudo

und ich möchte ~/test.py aufrufen mit

#!/usr/bin/python
import sys;print sys.path;
import mount_utils
print "Hallo Welt!"

mit sudo python ~/test.py, was zu Folgendem führt:

Traceback (most recent call last):
  File "/home/richter/test.py", line 3, in 
    import mount_utils
ImportError: No module named mount_utils

die Verzeichnisse in PYTHONPATH sind nicht in sys.path außer dem aktuellen Verzeichnis. python ~/test.py funktioniert wie erwartet (gibt sys.path und Hallo Welt! auf der Konsole aus). sudo -E python ~/test.py scheitert mit demselben Fehler. Ich verstehe nicht

  • Warum das Modul nicht verfügbar ist, wenn die PYTHONPATH-Variable im sudo echo-Output gedruckt wird
  • Warum sudo -E die Umgebung nicht beibehält (soweit ich aus man sudo und https://docs.python.org/2/using/cmdline.html verstehe, sollte es keinen Unterschied zwischen python bla und sudo -E python bla geben)

Warum erhalte ich diesen Fehler?

Überprüfung der Situation im Detail:

$ env | grep PYTHONPATH
PYTHONPATH=:/home/richter/scripts/python:/home/richter/scripts/python/installsystem:/home/richter/scripts/python/lib
$ sudo env | grep PYTHONPATH
$ LANG=C stat /home/richter/scripts/python/lib/mount_utils.py
  Datei: '/home/richter/scripts/python/lib/mount_utils.py'
  Größe: 8374        Blocks: 24         IO Block: 4096   normale Datei
Gerät: 80ch/2060d  Inode: 20972052    Links: 1
Zugriff: (0664/-rw-rw-r--)  Uid: ( 1000/ richter)   Gid: ( 1000/ richter)
Zugriff: 2014-08-19 17:06:37.542787417 +0200
Änderung: 2014-07-31 10:54:14.709468668 +0200
Verändert: 2014-07-31 10:54:14.729478917 +0200
 Geburt: -
$ LANG=C stat /home/richter/scripts/python/lib/__init__.py
  Datei: '/home/richter/scripts/python/lib/__init__.py'
  Größe: 0           Blocks: 0          IO Block: 4096   reguläre leere Datei
Gerät: 80ch/2060d  Inode: 20972114    Links: 1
Zugriff: (0664/-rw-rw-r--)  Uid: ( 1000/ richter)   Gid: ( 1000/ richter)
Zugriff: 2014-08-09 19:49:44.345055332 +0200
Änderung: 2014-05-07 06:57:31.434851243 +0200
Verändert: 2014-06-25 03:17:29.569551147 +0200
 Geburt: -

Ich habe keine Idee von der ziemlich ähnlichen unbeantworteten Frage Warum wird PYTHONPATH ignoriert?

EDIT 1: Nach Betrachtung von Wie setzt man die Umgebungsvariable für alle unter meinem Linux-System? und der Tatsache, dass echo ... ein recht schlechter Weg ist, um sicherzustellen, ob Umgebungsvariablen gesetzt sind, habe ich export PYTHONPATH="$PYTHONPATH:/home/richter/scripts/python:/home/richter/scripts/python/installsystem:/home/richter/scripts/python/lib" in

  • /etc/profile
  • /etc/profile.d/python_py.sh
  • /root/.bashrc
  • /home/richter/.bashrc

und jetzt ist PYTHONPATH (zusätzlich zur oben beschriebenen Situation) verfügbar in env im sudo -i Prompt, jedoch nicht in sudo env | grep PYTHONPATH. sudo python test.py scheitert immer noch aufgrund des gleichen Fehlers, d.h. mein Problem bleibt bestehen.

Außerdem scheitert export PYTHONPATH="/home/richter/scripts/python:/home/richter/scripts/python/installsystem:/home/richter/scripts/python/lib" && sudo -E python test.py aufgrund des gleichen Fehlers.

9voto

chown Punkte 50364

Sie müssen Ihre Umgebungsvariable PYTHONPATH zur env_keep von sudoers hinzufügen.

Führen Sie aus:
sudo visudo (öffnet die Datei /etc/sudoers auf sichere Weise).

Fügen Sie diese Zeile hinzu:
Defaults env_keep += "PYTHONPATH".

Jetzt :wq, und das wird die Variable PYTHONPATH beim Ausführen von sudo beibehalten.

1voto

Matt Warren Punkte 664

Könnte es sein, dass die Umgebung, unter der sudo läuft (root's), nicht den PYTHONPATH gesetzt hat?

sudo echo $PYTHONPATH

Bei diesem Befehl glaube ich, dass die Shell-Interpolation zuschlägt, bevor sudo ausgeführt wird, so dass du im Grunde genommen nur schreibst

sudo echo /home/richter/scripts/python:/home/richter/scripts/python/installsystem:/home/richter/scripts/python/lib

was wirklich nicht anders ist als

echo $PYTHONPATH

Ich sehe, dass du vielleicht in diese Richtung denkst mit sudo -E (obwohl ich das in deinen Beispielen nicht spezifisch sehe) - ich persönlich habe keine Erfahrung mit sudo -E.

Du könntest versuchen

sudo 'echo $PYTHONPATH'

Wo einfache Anführungszeichen die Interpolation stoppen, und auch

sudo -E 'echo $PYTHONPATH'

nur für den Fall, dass bei Verwendung von sudo -E das Problem mit der Shell-Interpolation wieder auftritt...

// Diese Vorschläge fallen mir spontan ein, deine Ergebnisse können variieren!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X