2010-04-12 5 views
5

Mine ist dieser Frage ähnlich.So kopieren Sie Dateien in den Netzwerkpfad oder Laufwerk mit Python

How to copy a file from a network share to local disk with variables?

Der einzige Unterschied ist mein Netzwerk-Laufwerk ein Passwort mit Benutzername und Passwort schützen hat.

Ich muss Dateien in eine Samba Freigabe mit Python kopieren und verifizieren.

Wenn ich mich manuell anmelde dann funktioniert der Code, aber ohne Anmeldung der shutil Befehl funktioniert nicht.

Antwort

9

Ich würde versuchen, den Anteil an einen freien Laufwerksbuchstaben zuordnen, indem Sie den Befehl NET USE Aufruf os.system verwenden (vorausgesetzt, Sie sind auf Windows):

os.system(r"NET USE P: \\ComputerName\ShareName %s /USER:%s\%s" % (password, domain_name, user_name)) 

Nachdem Sie die Aktie zu einem Laufwerksbuchstaben zugeordnet, können Sie Verwenden Sie shutil.copyfile, um die Datei auf das angegebene Laufwerk zu kopieren. Schließlich sollten Sie den Anteil aushänge:

os.system(r"NET USE P: /DELETE") 

Natürlich ist dies nur unter Windows funktioniert, und Sie werden dafür sorgen, dass die Laufwerksbuchstabe P zur Verfügung steht. Sie können den Rückkehrcode des Befehls NET USE überprüfen, um festzustellen, ob das Mounten erfolgreich war. Wenn nicht, können Sie einen anderen Laufwerksbuchstaben versuchen, bis Sie erfolgreich sind.

Da die beiden NET USE Befehle paarweise kommen und der zweite immer ausgeführt werden sollte, wenn der erste ausgeführt wurde (selbst wenn irgendwo dazwischen eine Ausnahme ausgelöst wurde), könnten Sie diese beiden Aufrufe in einen Kontextmanager umbrechen verwendet Python 2.5 oder höher:

from contextlib import contextmanager 

@contextmanager 
def network_share_auth(share, username=None, password=None, drive_letter='P'): 
    """Context manager that mounts the given share using the given 
    username and password to the given drive letter when entering 
    the context and unmounts it when exiting.""" 
    cmd_parts = ["NET USE %s: %s" % (drive_letter, share)] 
    if password: 
     cmd_parts.append(password) 
    if username: 
     cmd_parts.append("/USER:%s" % username) 
    os.system(" ".join(cmd_parts)) 
    try: 
     yield 
    finally: 
     os.system("NET USE %s: /DELETE" % drive_letter) 

with network_share_auth(r"\\ComputerName\ShareName", username, password): 
    shutil.copyfile("foo.txt", r"P:\foo.txt") 
+0

Hallo, was ist das Domain Name Argument? – user218976

+0

Das Doomain-Namensargument kann verwendet werden, wenn sich der Benutzer, der authentifiziert wird, in einer anderen Authentifizierungsdomäne befindet. Ich habe es nicht in die contextlib-Version aufgenommen, weil es einfach Teil des Benutzernamens sein kann. Wenn sich der Benutzer, der authentifiziert wird, in derselben Domäne wie der aktuelle Benutzer befindet, kann die Domäne weggelassen werden. –

+0

Danke ... es funktionierte ... nur manchmal, wenn ich es ein zweites Mal ausführen, bekomme ich eine Fehlermeldung, dass das lokale Gerät verwendet wird. – user218976

2

Wenn Sie die pywin32 Bibliothek (zB Teil der Activestate Python-Distribution kommt), dann können Sie es in ein paar Zeilen erledigen, ohne eine Laufwerkszuordnung:

import win32wnet 
win32wnet.WNetAddConnection2(0, None, '\\\\'+host, None, username, password) 
shutil.copy(source_file, '\\\\'+host+dest_share_path+'\\') 
win32wnet.WNetCancelConnection2('\\\\'+host, 0, 0) # optional disconnect 

Es gibt a more complete example on ActiveState Code

Verwandte Themen