Python copy files from Linux to WIndows
<p>I'm building a website which has a form which captures user data and runs some cgi on the user data.  One of the first steps of the cgi is that it needs to copy files from the linux webserver to windows machines.  The server would be using an active directory role acount for the copy credential.  I had hoped to simply use something like this:</p>

<p><pre><code></p>

<pre><code>mount -t cifs -o username=someUsername,password=somePasword //someMachine/someShare /someMountPoint
</code></pre>

<p></pre></code></p>

<p>Unfortunately I get errors about the password attributed being invalid when I run that command in bash.  Ideally I would use this method to mount the remote windows c$ share and then copy the files but I'm willing to try other modules if they make more sense.</p>

<p>I had something like this but it doesn't work, creates the necessary temporary directories but never mounts anything.  I'm happy to try using something else but would love to know what's wrong here.
<pre><code></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")
</code></pre>

<p></pre></code></p>

<p>First, drop the exception block as it hides error details, anyway <code>Popen</code> and other <code>subprocess</code> methods only throw exceptions when they cannot start commands (because of command not found), which means that <code>mount</code> is actually called.</p>

<p>Second, you really don't need <code>Popen</code>, but <code>call</code> (and as a bonus you get the return code directly)</p>

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

<p>In your case, the problem <em>is</em> the general exception block.</p>

<p>This method:</p>

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

<p>returns an <em>integer</em>, so if you remove the exception block you get error because you're adding a string with an integer (<code>TypeError: Can't convert 'int' object to str implicitly</code>). It's a simple mistake that you could have seen if it hadn't for the stupid exception catch which mislead you.</p>

<p>But with the generic <code>try/except</code> block without any argument, you just get <code>mount failed</code> useless message. <em>never</em> protect your statements with <code>try:/except:</code>, that's counter-productive.</p>

<p>If you <em>really</em> want to do that,do this:</p>

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

<p>Now to sum it up, here's a fixed version of your code (with some slight improvements as a bonus):</p>

<pre><code>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")
</code></pre>

python linux windows cifs