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")
我使用了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)
确保用户具有文件共享的登录权限。
这绝对是完美的解决方案。我已经删除了其他代码并用此代替它。我发现它更加可靠和快速。 非常感谢! –
这种方法有两个缺点:第一个是,你从你的网络服务器安装Windows共享。您不需要动态安装它,并且绝对不应该为每个请求安装它。分离您的实施和基础设施。在/ etc/fstab中挂载所需的目录,并让您的web服务器依赖目录的存在。
但是接下来还有另外一个问题:为什么要将文件复制到另一台机器上?你想在那里处理它们吗?你想如何通知Windows机器需要处理数据?为什么不在其上运行另一个Web服务器,并在需要处理某些内容时发送请求。此时,您可以删除所有网络文件系统并在请求中发送文件。所以你将有基于Linux的前端服务器,它通过向Windows后端服务器发送HTTP请求来执行一些操作。这也将允许您在处理准备就绪时通知前端。
谢谢,我明白你的意思。我想你明白了基本的想法。 linux apache服务器运行一个使用https并需要用户登录的表单。该表单收集的数据是用户名,一些其他简单变量和远程Windows桌面机主机名。这些数据用于创建应答文件,该文件被复制到远程桌面机器以及我不负责的其他软件组件。然后我需要在远程机器上触发一个exe文件。在此过程中所有内容都将被删除 –
首先,删除异常块,因为它隐藏了错误的详细信息,反正Popen
等subprocess
方法仅抛出异常时,他们无法启动(没有发现因为命令)命令,这意味着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")
非常感谢您的编辑。你说的很有道理,谢谢你的好建议! –
解决方案不是安装共享,而是使用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;"
谢谢大家的建议,最有帮助!
您想运行一个网站,该网站拥有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
是的,我同意关于帐户和理想的安装会应避免。这个网站将仅限于一小部分人,而且是内部的,但安全性显然非常重要。我无法真正使用远程机器上的共享,因为它们需要随时创建,但可能需要用户为此提供凭据。感谢输入,我一定会看看使用smbclient的可能性,我也喜欢那个tempfile模块的外观。谢谢 –