maxwhere
maxwhere

Reputation: 135

Python; how to properly call another python script as a subprocess

I know a very similar question has already been asked but since none of the solutions posted there worked for my problem I try to make it replicable:

So I'm calling this script to merge some shapefiles (all files in one folder) like this:

shpfiles = 'shapefile_a.shp shapefile_b.shp'
subprocess.call(['python', 'shapemerger.py', '%s' % shpfiles])

I only get the Usage Instructions from the script so I cant determine what goes wrong. If i call the script directly in the terminal it works. Any help is appreciated.

Upvotes: 0

Views: 7192

Answers (1)

VPfB
VPfB

Reputation: 17237

Every time a program is started, it receives a list of arguments it was invoked with. This is often called argv (v stands for vector, i.e. one-dimensional array). The program parses this list, extracts options, parameters, filenames, etc. depending on its own invocation syntax.

When working at the command line, the shell takes care of parsing the input line, starting new program or programs and passing them their argument list.

When a program is called from another program, the caller is responsible to provide the correct arguments. It could delegate this work to shell. The price for it is very high. There is substantial overhead and possibly a security risk! Avoid this approach whenever possible.

Finally to the question itself:

shpfiles = 'shapefile_a.shp shapefile_b.shp'
subprocess.call(['python', 'shapemerger.py', '%s' % shpfiles])

This will invoke python to run the script shapemerger.py with one argument shapefile_a.shp shapefile_b.shp. The script expects filenames and receives this one name. The file "shapefile_a.shp shapefile_b.shp" does not exist, but the script probably stops before attempting to access that file, because it expect 2 or more files to process.

The correct way is to pass every filename as one argument. Assuming shpfiles is a whitespace separated list:

subprocess.call(['python', 'shapemerger.py'] + shpfiles.split())

will generate a list with 4 items. It is important to understand that this approach will fail if there is a space in a filename.

Upvotes: 2

Related Questions