I've had the same problem with the subprocess module, attempting to multi-thread a process, and I've found that breaking up the arguments into individual components where spaces exit seems to work... contrary to what I've read; this may not be necessary on Linux or other platforms but on Windows it seems to be the way to go. By changing
args=['lasground', '-i *.las', output_file, ....
to
args=['lasground', '-i','*.las', output_file, ....
presents the arguments to the subprocess in a more digestible format; this seems true for any instance where a space appears in an argument. Another way that this can be done is by writing a temporary batch file and calling it with no arguments:
# give a batch file a random name eg: TempBat93314028.bat to avoid overwriting existing files
BatFile = os.path.join(os.environ.get("TEMP"),"TempBat{0}.bat".format(random.randint(0,sys.maxint)))
# just to be sure the name is clear.. be careful of race conditions! just because it doesn't exist
# -now- doesn't mean it won't be created by a different process -before- the next line!
# for this reason I would use a unique identifier for each process you intend to run, be creative!
# you're not limited to 8.3 filenames and can use spaces and underscores.
while os.path.exists(BatFile):
BatFile = os.path.join(os.environ.get("TEMP"),"TempBat{0}.bat".format(random.randint(0,sys.maxint)))
with open(BatFile,'w') as BatWrite:
# write the CMD on a single line, but this can get confusing
BatWrite.write("lasground -i {0}\\*.las {1} {2} {3} {4} {5} {6} {7}\n".format(PathToFiles, output_file, arg_step,
arg_spike, arg_spikedown, arg_offset,
arg_bulge, arg_cores))
# or bit by bit, a little more tedious but easier to modify
BatWrite.write("lasground ")
BatWrite.write("-i {0}\\*.las ".format(PathToFiles))
BatWrite.write("{0} ".format(output_file))
BatWrite.write("{0} ".format(arg_step))
BatWrite.write("{0} ".format(arg_spike))
BatWrite.write("{0} ".format(arg_spikedown))
BatWrite.write("{0} ".format(arg_offset))
BatWrite.write("{0} ".format(arg_bulge))
BatWrite.write("{0} ".format(arg_cores))
BatWrite.write("\n ") # end of line... or os.linesep to make this platform independent
proc=subprocess.Popen(BatFile,stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True)
output,error=proc.communicate()
# then later
os.remove(BatFile) # it's always good to clean up...
then if the process fails you've got the command as text you can run on a new instance to help with debugging.