Python 将文件从 Linux 复制到 WIndows
Python copy files from Linux to WIndows
我正在构建一个网站,该网站具有捕获用户数据的表单和 运行关于用户数据的一些 cgi。 cgi 的第一步是它需要将文件从 linux 网络服务器复制到 windows 机器。服务器将使用活动目录角色帐户作为复制凭据。我曾希望简单地使用这样的东西:
</p>
<pre><code>mount -t cifs -o username=someUsername,password=somePasword //someMachine/someShare /someMountPoint
不幸的是,当我 运行 在 bash 中执行该命令时,我收到有关密码无效的错误消息。理想情况下,我会使用这种方法挂载远程 windows c$ 共享,然后复制文件,但如果其他模块更有意义,我愿意尝试它们。
我有过类似的东西,但它不起作用,它创建了必要的临时目录,但从未安装任何东西。我很乐意尝试使用其他东西,但很想知道这里出了什么问题。
</p>
<pre><code>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")
这种方法有两个缺点:第一个是您从网络服务器装载 windows 共享。你不需要动态挂载它,无论如何你都不应该为每个请求挂载它。将您的实施和基础设施分开。在 /etc/fstab 中挂载所需的目录,让您的网络服务器依赖该目录的存在。
但是还有一个问题:你把文件复制到另一台机器上干什么?你想在那里处理它们吗?您想如何通知 windows 机器它需要处理数据?为什么不在其上 运行 另一个 Web 服务器并在需要处理某些内容时向其发送请求。此时您可以删除所有网络文件系统并在请求中发送文件。因此,您将拥有基于 linux 的前端服务器,它通过向 windows 后端服务器发送 HTTP 请求来执行一些操作。这也将允许您在处理准备就绪时通知前端。
首先,删除异常块,因为它隐藏了错误详细信息,无论如何 Popen
和其他 subprocess
方法仅在无法启动命令时抛出异常(因为找不到命令),这意味着mount
实际被调用了
其次,您确实不需要 Popen
,但是 call
(作为奖励,您可以直接获得 return 代码)
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
returns 一个 整数 ,所以如果你删除异常块,你会得到错误,因为你添加了一个带有整数的字符串(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;"
谢谢大家的指点,很有帮助!
我使用了在 pysmb (https://pythonhosted.org/pysmb/api/smb_SMBConnection.html) 中找到的 SMBConnection class。非常简单,无需安装。
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 )
确保用户具有文件共享的登录权限。
我正在构建一个网站,该网站具有捕获用户数据的表单和 运行关于用户数据的一些 cgi。 cgi 的第一步是它需要将文件从 linux 网络服务器复制到 windows 机器。服务器将使用活动目录角色帐户作为复制凭据。我曾希望简单地使用这样的东西:
</p>
<pre><code>mount -t cifs -o username=someUsername,password=somePasword //someMachine/someShare /someMountPoint
不幸的是,当我 运行 在 bash 中执行该命令时,我收到有关密码无效的错误消息。理想情况下,我会使用这种方法挂载远程 windows c$ 共享,然后复制文件,但如果其他模块更有意义,我愿意尝试它们。
我有过类似的东西,但它不起作用,它创建了必要的临时目录,但从未安装任何东西。我很乐意尝试使用其他东西,但很想知道这里出了什么问题。
</p>
<pre><code>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")
这种方法有两个缺点:第一个是您从网络服务器装载 windows 共享。你不需要动态挂载它,无论如何你都不应该为每个请求挂载它。将您的实施和基础设施分开。在 /etc/fstab 中挂载所需的目录,让您的网络服务器依赖该目录的存在。
但是还有一个问题:你把文件复制到另一台机器上干什么?你想在那里处理它们吗?您想如何通知 windows 机器它需要处理数据?为什么不在其上 运行 另一个 Web 服务器并在需要处理某些内容时向其发送请求。此时您可以删除所有网络文件系统并在请求中发送文件。因此,您将拥有基于 linux 的前端服务器,它通过向 windows 后端服务器发送 HTTP 请求来执行一些操作。这也将允许您在处理准备就绪时通知前端。
首先,删除异常块,因为它隐藏了错误详细信息,无论如何 Popen
和其他 subprocess
方法仅在无法启动命令时抛出异常(因为找不到命令),这意味着mount
实际被调用了
其次,您确实不需要 Popen
,但是 call
(作为奖励,您可以直接获得 return 代码)
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
returns 一个 整数 ,所以如果你删除异常块,你会得到错误,因为你添加了一个带有整数的字符串(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;"
谢谢大家的指点,很有帮助!
我使用了在 pysmb (https://pythonhosted.org/pysmb/api/smb_SMBConnection.html) 中找到的 SMBConnection class。非常简单,无需安装。
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 )
确保用户具有文件共享的登录权限。