Linux Pro
Linux Pro

Reputation: 468

Cant pass arguments to perl script using python

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

Answers (1)

Joe Halliwell
Joe Halliwell

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

Related Questions