Search code examples
pythonparametersftpsubprocesswinscp

Run WinSCP script in Python with parameters


I'm trying to run a WinSCP script that has a parameter %1%. I run the script in cmd as follows an d it runs fine:

"C:\Program Files (x86)\WinSCP\WinSCP.com" /script=<filepath> /log=<logpath> /parameter <param1>

But if I can't figure out how to pass the param1 value if I run it as a subprocess in Python. What am I doing wrong? I tried:

cmdFile = <filepath>
logfile = <logpath>
param = <param1>
subprocess.run(["C:\Program Files (x86)\WinSCP\WinSCP.com", "/script=" + cmdFile, "/log=" + logfile, param]  , shell=True)
subprocess.run(["C:\Program Files (x86)\WinSCP\WinSCP.com", "/script=" + cmdFile, "/log=" + logfile, "/parameter " + param]  , shell=True)
subprocess.run(["C:\Program Files (x86)\WinSCP\WinSCP.com", "/script=" + cmdFile, "/log=" + logfile, "/parameter //" + param]  , shell=True)```

Solution

  • Here is a self-contained example that solves your issue and can easily be tested by running some small local ftp host like ftpdmin (https://www.sentex.ca/~mwandel/ftpdmin/, no affiliation):

    import subprocess
    
    # create a test file
    test_fn = 'test.txt'
    with open(test_fn, 'w') as f:
        f.write(
            'Hello\n'
            'World\n'
        )
    
    # create a script for WinSCP
    script_fn = 'commands.txt'
    with open(script_fn, 'w') as f:
        f.write(
            'open ftp://anonymous:@localhost\n'
            'put "%1%"\n'
            'put "%2%"\n'
            'exit'
        )
    
    log_fn = 'log.txt'
    # parameters to pass to the script (uploading the test file and the script)
    parameters = [test_fn, script_fn]
    # the adjusted command, passing '/parameter' and then just the parameters
    subprocess.run([
        'C:\Program Files (x86)\WinSCP\WinSCP.com',
        '/script=' + script_fn,
        '/log=' + log_fn,
        '/parameter'
    ] + parameters, shell=True)
    

    Note that I changed the variable names to be a bit more Pythonic, they weren't wrong, but there's always room for improvement :).

    The issue with your own solutions was that you need to pass parameters to your script after a single /parameter parameter on the command line. For example:

    winscp.com /script=commands.txt /parameter one two three
    

    This would start the script in commands.txt and pass one, two and three to the script, where they would be accessible as %1% etc. (note that WinSCP recommends you surround them with quotes in the script if they can contain spaces)

    In your attempts, you pass 1.) just the parameter, 2.) '/parameter param' as a single string, instead of two as expected by .run() and 3.) '/parameter //param' which has the same problem, but adds a superfluous double slash.

    In the form that you wrote it, this would have been correct:

    subprocess.run(["C:\Program Files (x86)\WinSCP\WinSCP.com", "/script=" + cmdFile, "/log=" + logfile, "/parameter", param], shell=True)