Reputation: 468
I'm trying to do what should be a simple action-- execute a perl script from within a python3 script, passing several arguments to the perl script. Here's what I've tried, nothing works:
Approach 1 -- the perl script runs, but the arguments aren't passed
addexec = "../perl/bin/engine.pl"
addvars = " --uid " + str(our_id) + " --url '" + source_url + "'"
addtodb = subprocess.Popen(["/usr/bin/perl", addexec, addvars])
Approach 2 -- the perl script doesn't run, says file not found
addexec = "../perl/bin/engine.pl --uid " + str(our_id) + " --url '" + source_url
addtodb = subprocess.Popen(["/usr/bin/perl", addexec])
Approach 3 -- the perl script doesn't run, generates errors
addcmd = ["/usr/bin/perl", "../perl/bin/engine.pl", " --uid ", str(our_id), " --url '", source_url, "'"]
addtodb = subprocess.Popen(addcmd)
Anyone have any suggestions? Thanks!
Upvotes: 2
Views: 816
Reputation: 1177
Approach 3 looks broadly correct, but you almost certainly don't want to "quote" the URL, need to provide the correct script path, and want to pass a single list to Popen
. Try:
addcmd = ["/usr/bin/perl", "../perl/bin/engine.pl", "--uid", str(our_id), "--url", source_url]
addtodb = subprocess.Popen(addcmd)
Update: incorporated fix from @AJefferiss
There seems to be an underlying misconception here around how program arguments are handled.
A command shell determines program arguments by parsing user input -- typically splitting on spaces (except where enclosed in quotes). In contrast, the underlying APIs like Popen
accept a list of arguments directly.
The upshot is that when using such APIs 1) you don't need the quotes, and 2) you need to drop extra spaces around arguments. It's also why you can't (generally) use shell syntax like ~
, wildcard expansion or environment variables.
Upvotes: 5