0

To run a command in python, for Windows, I do:

import subprocess
subprocess.check_output(lsCommand, shell=True)

where lsCommand is a list of strings that make up the bash command. This works, except when it contains some input with spaces in it. For example, copying + changing a name:

To try and do cp "test 123" test123:

lsCommand = ['cp', 'test 123', 'test123']
subprocess.check_output(lsCommand, shell=True)

fails because it thinks I am trying to do cp "test" "123" test123. Error (doing google storage stuff):

python: can't open file 'c:\GSUtil\gsutil.py cp -n gs://folderl/test': [Errno 22] Invalid argument

Then I try

subprocess.check_output('cp "test 123" test123', shell=True)

Same shit. Any ideas?

Roman
  • 8,826
  • 10
  • 63
  • 103
  • 1
    Why are you using `shell=True`? Given a list without `shell=True` should work I think. – zondo Mar 31 '16 at 13:46
  • @zondo not on windows, no. Linux yay – Roman Mar 31 '16 at 13:47
  • See also http://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess – tripleee Mar 31 '16 at 13:51
  • doing anything without `shell=True` fails for me. Several questions I read stated that it is required in Windows. For example http://stackoverflow.com/questions/9531683/problems-using-subprocess-call-in-python-2-7-2-on-windows – Roman Mar 31 '16 at 13:54
  • You appear to be running cp.exe from some Unix-like environment (e.g. MSYS), so there's no need to run the command via cmd.exe, i.e. `shell=True` on Windows. Your life will be simpler without it. Also, never use an args list with `shell=True` on either Windows or Unix systems. (It's for different reasons on Windows vs. Unix, but the same advice applies.) – Eryk Sun Mar 31 '16 at 13:57
  • Roman: It was required there because `cmd` is an internal command. – zondo Mar 31 '16 at 13:58
  • 1
    What error do you get without using the cmd shell? – Eryk Sun Mar 31 '16 at 13:59
  • Thanks everyone for your input. Unfortunately I'll have to wait till tomorrow to reply to you @eryksun. They shut the vpn down and the guy just went home. I'll test as soon as I can and will post the results. – Roman Mar 31 '16 at 14:03
  • FYI, using `subprocess` at all here is kind of silly, when Python supports it directly, no external program nonsense, with [`shutil.copyfile`](https://docs.python.org/3/library/shutil.html#shutil.copyfile). – ShadowRanger Mar 31 '16 at 14:35

2 Answers2

0

cp is not an internal command and therefore you don't need shell=True (though you might need to specify a full path to cp.exe).

The internal interface for starting a new subprocess on Windows uses a string i.e., it is up to the specific application how to interpret a command-line. The default MS C runtime rules (imlemented in subprocess.list2cmdline() that is called implicitly if you pass a list on Windows) should work fine in this case:

#!/usr/bin/env python
from subprocess import check_call

check_call(['cp', 'test 123', 'test123'])

If you want to use shell=True then the program that interprets the command line is cmd.exe and you should use its escape rules (e.g., ^ is a meta-character) and pass the command as a string as is (as you see it in the Windows console):

check_call('copy /Y /B "test 123" test123', shell=True)

Obviously, you don't need to start an external process, to copy a file in Python:

import shutil

shutil.copy('test 123', 'test123')
Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670
0

for Ubuntu:

subprocess.check_output(['list', 'of', 'commands with spaces'])

for Windows:

subprocess.check_output('single command "string with spaces"')

Thanks for info that I don't need shell=True.

Roman
  • 8,826
  • 10
  • 63
  • 103