<div dir="ltr"><div class="gmail_quote">On Mon Feb 16 2015 at 7:40:42 PM Peter Otten <__<a href="mailto:peter__@web.de" target="_blank">peter__@web.de</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">David Aldrich wrote:<br>
<br>
> Hi Peter<br>
><br>
> Thanks very much for your reply. I have added one more question below.<br>
><br>
>> The straightforward approach is to pass a list or tuple:<br>
>><br>
>> def build(build_options=()):<br>
>>     subprocess_check_call(("make"<u></u>,<u></u>) + build_options)<br>
>><br>
>> build(("flagA=true", "flagB=true"))<br>
><br>
> This looks fine - I am trying it.<br>
><br>
> I would like to display on the console the entire make command, so I have<br>
> done this:<br>
><br>
> def build(build_options=()):<br>
>         make_command = 'make '.join(map(build_options))<br>
>         print('Build command: ' + make_command)<br>
>         subprocess.check_call(("make"<u></u>,<u></u>)+build_options)<br>
><br>
> but I get error:<br>
><br>
> make_command = 'make '.join(map(build_options))<br>
> TypeError: map() must have at least two arguments.<br>
><br>
> What would be the correct way to concatenate and display the elements in<br>
> the tuple please?<br>
<br>
Hm, what do you expect map() to achieve? And "make " is not really the<br>
string you want as a separator...<br>
<br>
You can join the strings in build_options with<br>
<br>
>>> build_options = "foo", "bar", "baz"<br>
>>> " ".join(build_options)<br>
'foo bar baz'<br>
>>> "make " + " ".join(build_options)<br>
'make foo bar baz'<br>
<br>
But you shouldn't do this as you have already learnt that spaces do not<br>
separate arguments; in fact by default check_call() doesn't even use the<br>
shell. An example to drive the point home:<br>
<br>
>>> from subprocess import check_call<br>
>>> check_call(["python3", "-c", "import sys; print(sys.argv[1:])", "foo",<br>
"bar"])<br>
['foo', 'bar']<br>
0<br>
>>> check_call(["python3", "-c", "import sys; print(sys.argv[1:])", "foo<br>
bar"])<br>
['foo bar']<br>
<br>
Both invocations would appear to issue the same command in your debugging<br>
print() call. list2cmdline() does a bit better; it resembles the command<br>
issued if the shell were used:<br>
<br>
>>> print(subprocess.list2cmdline(<u></u><u></u>["make"] + build_options))<br>
make foo "bar baz"<br></blockquote><div><br></div><div>It's also possible to do it the other around using shlex.split. I prefer that version because I can easily copy/paste the command from code to the shell, it's also more readable IMO:</div><div><span style="font-size:13.1999998092651px"><br></span></div><div><div>> cmd = """python3 -O -c "import sys; print(sys.argv[1:])" foo <span style="font-size:13.1999998092651px">bar "spam egg" """</span></div></div><div><span style="font-size:13.1999998092651px">> print(cmd)</span></div><div>> subprocess.check_call(shlex.split(cmd))<br></div><div><span style="font-size:13.1999998092651px"><br></span></div><div>shlex.split(cmd) must be prefered to cmd.split('') which doesn't take into account shell strings. paths with space must be wrapped in quote (<span style="font-size:13.1999998092651px">talking of path, pathlib is awesome)</span><span style="font-size:13.1999998092651px">.</span></div><div><br></div><div><a href="https://docs.python.org/2.7/library/shlex.html?highlight=shlex#shlex.split">https://docs.python.org/2.7/library/shlex.html?highlight=shlex#shlex.split</a><br></div><div><br></div><div><br></div><div>Regards</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
--<br>
<a href="https://mail.python.org/mailman/listinfo/python-list" target="_blank">https://mail.python.org/<u></u>mailma<u></u>n/listinfo/python-list</a><br>
</blockquote></div></div>