7

我的类似于这个问题。

如何使用变量将文件从网络共享复制到本地磁盘?

唯一的区别是我的网络驱动器有一个密码保护用户名和密码。

我需要将文件复制到Samba共享Python并验证它。

如果我手动登录,则代码可以工作,但如果不登录,该shutil命令将不起作用。

4

2 回答 2

11

I'd try mapping the share to an unused drive letter by calling the NET USE command using os.system (assuming you are on Windows):

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

After you mapped the share to a drive letter, you can use shutil.copyfile to copy the file to the given drive. Finally, you should unmount the share:

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

Of course this works only on Windows, and you will have to make sure that the drive letter P is available. You can check the return code of the NET USE command to see whether the mount succeeded; if not, you can try a different drive letter until you succeed.

Since the two NET USE commands come in pair and the second one should always be executed when the first one was executed (even if an exception was raised somewhere in between), you might wrap these two calls in a context manager if you are using Python 2.5 or later:

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")
于 2010-04-12T23:23:31.367 回答
4

如果你有 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 Code上有一个更完整的例子

于 2014-09-07T12:21:33.873 回答