How to get this Subprocess to work

Hi all,

I’m calling the function below using xlWings, a Python package that integrates with Excel. As you can see below, it is supposed to create a subprocess and execute a separate python script and supply the paramaters, but it is not doing anything. To debug, I printed the full command along with parameters that is sent to the subprocess, and tried executing it in command prompt. That worked just fine.

Any idea what I’m doing wrong? I’m using Windows 10 and Python 3.9.2. Note that the path to home directory contains spaces, so I’ve been using double quotes around it.

def exitPosition():
        import logging, subprocess

        smb = 'TSLA'
        mp = getCurrentPrice()

        # Place order in a subprocess
        command = ['cd "full path to home directory" &', 'python', 'relative path from the home directory to the python script ', 'EXIT', smb, mp]
        subprocess.Popen(command, shell=True)

    except Exception as e:
        log_file = 'Testing.log'
        logging.basicConfig(filename=log_file, format='%(asctime)s - %(message)s', datefmt='%d-%b-%y %H:%M:%S', level=logging.ERROR)
        logging.exception('Exception occurred')

Using an argument list with shell=True is wrong on both POSIX and Windows, for different reasons. On Windows it’s wrong because subprocess has to build a command line from the list via subprocess.list2cmdline(). This function assumes C/C++ argv parsing rules, but the CMD shell uses completely different rules. In particular, list2cmdline() uses backslash to escape double quote characters, but CMD only supports caret as an escape character. Moreover, converting an argument list for use by CMD is complicated because it has to support CMD’s often bizarre behavior (e.g. “%” can’t be escaped, not really), plus that of any other executables used in the command line, which generally follow the C/C++ argv rules, but not always (e.g. Cygwin programs have their own ideas about the command line). It’s left up to the developer to hand craft a command line that works in each case.

If you just need to change the working directory of the child Python process, use the cwd parameter. For example:

command = ['python', 'relative path to python script', 'EXIT', smb, mp]
subprocess.Popen(command, cwd='full path to home directory')

Worked like a charm, thank you!