2

Say I want to do: subprocess.call(['whatever.exe',v]) where v is a string representing all the arguments to pass to whatever.exe. Is there a way to do this without breaking apart each argument individually?

5
  • 1
    What do you want to happen when arguments contain spaces? Quotes? Globs? (The value of passing an explicit list is that it's... well... explicit; all the expansion and splitting has been done ahead-of-time and under your control). Commented Jun 20, 2017 at 20:33
  • It's my code all the way down, it won't. Commented Jun 20, 2017 at 21:02
  • 1
    That's not always a sure thing, even when it is your own code. The biggest data loss issue I've personally witnessed was caused by a new program (which used a Python module with a bug where it was careless with a pointer) written in-house by our own people generating filenames with whitespace and globs (and other random content from memory) in a directory that "couldn't ever" include anything but names composed purely of hex digits. Script tries to delete that one file -> script deletes all our backups used to support customer billing. Commented Jun 20, 2017 at 21:07
  • 1
    ...which is to say: Defensive programming doesn't matter until it does, but when it matters, it really matters. Commented Jun 20, 2017 at 21:08
  • Yikes. Changed to shlex.split. Commented Jun 20, 2017 at 21:29

1 Answer 1

2

yes, you can pass the full command line as a string:

subprocess.call('whatever.exe {}'.format(v)) 

but it's not a very good idea because if some arguments contained in v have spaces in it you have to do the quoting manually (and as Charles reminded me for the 50th time it only works on Windows unless shell=True is set, which is another bad idea)

Another option would be using shlex.split and append to your already existing argument list (if executable has spaces in the path at least it is handled):

subprocess.call(['whatever.exe']+shlex.split(v)) 

but the best option is composing the list of arguments properly of course (as an actual list), and not passing a string to subprocess at all (safety, security & portability reasons to start with). If you're controlling what's in v you can change as a list, and if you don't, well, you're probably exposing your program to a possible attack or denial of service)

Sign up to request clarification or add additional context in comments.

6 Comments

Is there a reason to concatenate strings via 'whatever.exe {}'.format(v) instead of 'whatever.exe ' + v?
Yes: you just forgot to append a space between whatever.exe and the rest of the arguments :). str.format is clearer.
+1 on the shlex.split(); -1 on the "pass the full command line as a string" (Windows is a different beast, but on UNIX that just won't work without shell=True), so right now I'm at =0.
@CharlesDuffy I will edit. OP is using windows (you already told me that but I tend to forget that :))
Reading in the platform from the .exe extension, or did they say it explicitly somewhere? (CLR binaries are executable on UNIX systems where binfmt_misc or an equivalent has been used to tell Mono to invoke them).
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.