Search code examples
pythonpython-3.xapibatch-filecmd

Calling batch commands from python


I am using python with some external program API in order to automate some stuff. Have in mind that these "extpro" and "--file" and "--dont-breakaway-from-job" are built in commands that I have to use, my code looks like this:

send = os.system('extpro --file '(os.path.join(base_dir, extpr_path))' --dont-breakaway-from-job')

Error that I am getting is on the --dont-breakaway-from-job, saying Expected ")" pylance.

But when I try this there is no error:

send = os.system('extpro --file "C:/user/program/run.exe" --dont-breakaway-from-job')

Anyone have idea what might be behind this behavior? Is there a way maybe to split whole command into two or three?

Any advice is welcome, thanks!


Solution

  • os.path.join returns str object, thus your

    'extpro --file '(os.path.join(base_dir, extpr_path))' --dont-breakaway-from-job'
    

    expands into:

    'extpro --file '"<whatever that path is>"' --dont-breakaway-from-job'
                   ^                                    
    

    In the position marked with ^ the string ends. And, since os.system expects only one single parameter, pylance (and interpreter too) supposes, that this parameter is already passed and throws an error, that closing bracket is expected.

    Interpreter doesn't concatenate os.path.join result with string before it, because it doesn't know, that os.path.join is a string. Function call will become string only in runtime.

    However, your second variant contains 'some str "inner str" some more'. Python interpreter sees string, starting with ' (single qotation mark) and looks for a matching pair, that will mean end of the string. All " (double quotation marks) between single ones are considered part of the string.

    Solution is simple. You can do any of:

    # Concatenating strings with +
    send = os.system('extpro --file "'+ os.path.join(base_dir, extpr_path) + '" --dont-breakaway-from-job')
    # Using format (or f-strings, ifyou're using python 3.6+)
    send = os.system('extpro --file "{}" --dont-breakaway-from-job'.format(os.path.join(base_dir, extpr_path)))
    # or
    send = os.system(f'extpro --file "{os.path.join(base_dir, extpr_path)}" --dont-breakaway-from-job')
    

    In any of 3 variations it's worth wrapping os.path.join results with " (double quotation mark) in case it contains spaces or other undesired symbols, that may e parsed incorrectly