Как скопировать файлы в сетевой путь или на диск с помощью Python

Мой похож на этот вопрос.

Как скопировать файл из сетевой папки на локальный диск с переменными?

Единственная разница в том, что мой сетевой диск защищен паролем с именем пользователя и паролем.

Мне нужно скопировать файлы в общий ресурс Samba с помощью Python и проверить его.

Если я вхожу в систему вручную, код работает, но без входа в систему команда shutil не работает.


person user218976    schedule 12.04.2010    source источник


Ответы (2)


Я бы попытался сопоставить общий ресурс с неиспользуемой буквой диска, вызвав команду NET USE с помощью os.system (при условии, что вы работаете в Windows):

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

После того, как вы сопоставили общий ресурс с буквой диска, вы можете использовать shutil.copyfile для копирования файла на указанный диск. Наконец, вы должны размонтировать общий ресурс:

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

Конечно, это работает только в Windows, и вам нужно будет убедиться, что буква диска P доступна. Вы можете проверить код возврата команды NET USE, чтобы увидеть, удалось ли монтирование; если нет, вы можете попробовать другую букву диска, пока не добьетесь успеха.

Поскольку две команды NET USE идут парами, а вторая всегда должна выполняться одновременно с первой (даже если где-то между ними возникло исключение), вы можете обернуть эти два вызова в контекстный менеджер, если используете Python 2.5. или позже:

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")
person Tamás    schedule 12.04.2010
comment
Привет, что такое аргумент имени домена? - person user218976; 13.04.2010
comment
Аргумент имени домена можно использовать, когда аутентифицируемый пользователь находится в другом домене аутентификации. Я не включил его в версию contextlib, потому что его можно просто сделать частью имени пользователя. Если аутентифицируемый пользователь находится в том же домене, что и текущий пользователь, домен можно не указывать. - person Tamás; 13.04.2010
comment
Спасибо ... это сработало ... только иногда, если я запускаю его во второй раз, я получаю сообщение об ошибке, говорящее, что локальное устройство используется. - person user218976; 14.04.2010
comment
Спасибо за это ... использование Subprocess вызвало много проблем, но ваш метод os.system работал отлично! - person Conor; 11.08.2015
comment
5 лет спустя... это помогло мне. Ваше здоровье - person Busturdust; 29.10.2015

Если у вас есть библиотека pywin32 (например, входит в состав дистрибутива ActiveState Python), вы можете сделать это в несколько строк, не подключая диск:

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

Существует более полный пример кода ActiveState.

person Mark Foreman    schedule 07.09.2014