2

Inside a Flask app I try to run Python subprocess module. All worked on Ubuntu 12.04 with Python 2.7.8 and now I'm trying to check if the app works on Windows as well (Win7 x64, Python 2.7.12). My piece of code that works on Linux:

try:
    command = ["pgsql2shp -f %s -h %s -u %s -P %s %s main.%s" % (path, host, user, pword, db_name, region)] 

    work = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

Above doesn't on Windows, returning stderr like "The filename directory name or volume syntax is incorrect".

But:

try:
    work = subprocess.Popen("pgsql2shp -f %s -h %s -u %s -P %s %s main.%s" % (path, host, user, pword, db_name, region), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

Above works on Windows! What is the reason here? The error brought me to thinking that my path variable is incorrect, but it is as below:

path = 'D:/adam/files/test.shp'
print path # D:/adam/files/test.shp

path = os.normpath(path)
print path # D:\adam\files\test.shp
path # 'D:\\adam\\files\\test.shp'

If I run postgres' pgsql2shp from Windows cmd and just paste whatever combination of \, \\ or / in string and the data I use here, it works good. Looks like pgsql2sgp converts the path to needed format itself. Then why it won't work through Python script and separate command variable?

adamczi
  • 343
  • 1
  • 7
  • 24
  • See http://stackoverflow.com/questions/15109665/subprocess-call-using-string-vs-using-list – cdarke Sep 27 '16 at 11:00
  • Thank you, that link helps me to deal with other problems I have with `subprocesses`, but to this question what actually helped me is a comment that is already deleted (was it yours, @cdarke ?) - the argument should be a list so, I just put `command` into `[ ]` and all is fine. – adamczi Sep 27 '16 at 11:18
  • it was my comment, but I thought the other question answered it more fully. Glad is now OK. – cdarke Sep 27 '16 at 12:52
  • Never use an args list with `shell=True`, especially not on Windows. `subprocess.list2cmdline` doesn't have a clue about how to properly quote and escape a command line for cmd.exe and subsequent child processes. – Eryk Sun Sep 27 '16 at 13:35
  • Thank you for this comment. You said "especially not on Windows", however I tried `shell=False` on Ubuntu and couldn't make it work any way (with `command` being a list or a string and passed as `[command]` or `command`. Seems not to work for me on Ubuntu with `False` – adamczi Sep 27 '16 at 15:49
  • A Unix novice may be in for a surprise when using an args list. What happens is the arguments are passed to the shell itself, e.g. try `subprocess.call(['echo $0 $1', 'spam', 'eggs'], shell=True)`. – Eryk Sun Sep 27 '16 at 17:33
  • yes, in my case, just as in your example, the shell must then be `True` in Unix. thank you! – adamczi Sep 28 '16 at 07:53

0 Answers0