Python从Linux复制文件到WIndows

问题描述:

我正在建立一个网站,其中有一个表格可以捕获用户数据并在用户数据上运行一些cgi。 cgi的第一步就是需要将文件从linux webserver复制到windows机器上。服务器将使用活动目录角色帐户作为副本凭证。我希望简单地使用这样的事情:Python从Linux复制文件到WIndows

mount -t cifs -o username=someUsername,password=somePasword //someMachine/someShare /someMountPoint 

不幸的是我得到了密码错误归于无效时,当我在bash中运行该命令。理想情况下,我会使用这种方法来安装远程窗口c $共享,然后复制文件,但我愿意尝试其他模块,如果他们更有意义。

我有这样的东西,但它不起作用,创建必要的临时目录,但从不安装任何东西。我很乐意尝试使用别的东西,但很想知道这里有什么问题。

import subprocess 
import random 


def makeDir(): 
    tempDir = random.randrange(111111,999999) 
    subprocess.Popen(["mkdir","/mntDir/"+str(tempDir)]) 
    return tempDir 

def mountShare(hostname, username, password): 
    mountDir = makeDir() 
    try: 
     subprocess.Popen(["mount","-t","cifs", "-o", 
         "username="+username+",password="+password, 
         "//"+hostname+"/c$", 
         "/mntDir/"+mountDir]) 
    except: 
     print("Mounting failed") 

+0

您想运行一个网站,该网站拥有Windows服务器的管理员权限(C $共享所需的权限)以及在Linux服务器上安装文件系统的root权限,以实现日常的普通操作?好恶。更好的方法是在Windows服务器上使用有限的用户帐户,只需拥有正确的文件夹和共享权限,以及Linux端的[smbclient](http://superuser.com/a/562728),以避免必须安装共享。 (另外,请检查[tempfile](https://docs.python.org/3/library/tempfile.html)模块,以避免你的random.randrange bodge) – TessellatingHeckler

+0

是的,我同意关于帐户和理想的安装会应避免。这个网站将仅限于一小部分人,而且是内部的,但安全性显然非常重要。我无法真正使用远程机器上的共享,因为它们需要随时创建,但可能需要用户为此提供凭据。感谢输入,我一定会看看使用smbclient的可能性,我也喜欢那个tempfile模块的外观。谢谢 –

我使用了pysmb(https://pythonhosted.org/pysmb/api/smb_SMBConnection.html)中的SMBConnection类。非常简单,无需安装。

conn = SMBConnection(user, pw, myname, srv, use_ntlm_v2 = True) 
conn.connect(ip, port=139) 
file2transfer = open(filename,"r") 
conn.storeFile(share,path + filename, file2transfer, timeout=30) 

确保用户具有文件共享的登录权限。

+0

这绝对是完美的解决方案。我已经删除了其他代码并用此代替它。我发现它更加可靠和快速。 非常感谢! –

这种方法有两个缺点:第一个是,你从你的网络服务器安装Windows共享。您不需要动态安装它,并且绝对不应该为每个请求安装它。分离您的实施和基础设施。在/ etc/fstab中挂载所需的目录,并让您的web服务器依赖目录的存在。

但是接下来还有另外一个问题:为什么要将文件复制到另一台机器上?你想在那里处理它们吗?你想如何通知Windows机器需要处理数据?为什么不在其上运行另一个Web服务器,并在需要处理某些内容时发送请求。此时,您可以删除所有网络文件系统并在请求中发送文件。所以你将有基于Linux的前端服务器,它通过向Windows后端服务器发送HTTP请求来执行一些操作。这也将允许您在处理准备就绪时通知前端。

+0

谢谢,我明白你的意思。我想你明白了基本的想法。 linux apache服务器运行一个使用https并需要用户登录的表单。该表单收集的数据是用户名,一些其他简单变量和远程Windows桌面机主机名。这些数据用于创建应答文件,该文件被复制到远程桌面机器以及我不负责的其他软件组件。然后我需要在远程机器上触发一个exe文件。在此过程中所有内容都将被删除 –

首先,删除异常块,因为它隐藏了错误的详细信息,反正Popensubprocess方法仅抛出异常时,他们无法启动(没有发现因为命令)命令,这意味着mount实际上是调用。

其次,你真的不需要Popen,但call(和作为奖金,你直接将返回代码)

rc = subprocess.call(["mount","-t","cifs", "-o", 
         "username="+username+",password="+password, 
         "//"+hostname+"/c$", 
         "/mntDir/"+mountDir]) 
if rc: 
    print("mount failed") 

在你的情况下,问题一般异常块。

这种方法:

def makeDir(): 
    tempDir = random.randrange(111111,999999) 
    subprocess.Popen(["mkdir","/mntDir/"+str(tempDir)]) 
    return tempDir 

返回一个整数,因此,如果您删除异常块,因为你要添加一个字符串一个整数(TypeError: Can't convert 'int' object to str implicitly),你会得到错误。这是一个简单的错误,你可以看到它是否不适合愚蠢的例外情况,误导你。

但与通用的try/except块没有任何参数,你只是得到mount failed无用的消息。 从来没有保护你的陈述与try:/except:,这是适得其反。

如果你真的想这样做,这样做:

try: 
    some_command 
except Exception as e: 
    # print detailed exception, not just "error" 
    print("Something went wrong "+str(e)) 

现在总结一下,这里是你的代码的固定版本(稍作改进作为奖金):

import subprocess,os 
import random 


def makeDir(): 
    # directly create directory name as a string 
    tempDir = "/mntDir/{}".format(random.randrange(111111,999999)) 
    # no need for a subprocess, python handles this well! 
    os.mkdir(tempDir) 
    # returns the absolute directory name, as string 
    return tempDir 

def mountShare(hostname, username, password): 
    mountDir = makeDir() 
    rc = subprocess.call(["mount","-t","cifs", "-o", 
         "username="+username+",password="+password, 
         "//"+hostname+"/c$", 
         mountDir]) 
    if rc!=0: 
     print("Mounting failed") 
+0

非常感谢您的编辑。你说的很有道理,谢谢你的好建议! –

解决方案不是安装共享,而是使用smbclient进行即时复制。我使用的命令是指包含在表单中的相关权限的帐户的authfile:

username = yourUsername 
password = yourPassword 
domain = yourDomain 

该文件的权限设置为500

的smbclient的命令然后使用在远程机器上创建一个目录并将文件复制到该目录。

smbclient //hostname/c$ -A /authfile -c "mkdir someDir; cd someDir/; lcd /folderToCopyFrom; prompt; recurse; mput *; exit;" 

谢谢大家的建议,最有帮助!