79

I would like to run a command in Python Shell to execute a file with an argument.

For example: execfile("abc.py") but how to add 2 arguments?

NoDataDumpNoContribution
  • 10,591
  • 9
  • 64
  • 104
olidev
  • 20,058
  • 51
  • 133
  • 197
  • How is the code in the file you want to execute retrieve the arguments? – martineau Apr 26 '11 at 11:42
  • I know this is old question, but you could alternately probably pass values to run a py file in a file and just open it up and read in the values. – p wilson Apr 08 '21 at 02:01

13 Answers13

60

Actually, wouldn't we want to do this?

import sys
sys.argv = ['abc.py','arg1', 'arg2']
execfile('abc.py')
user2757262
  • 609
  • 5
  • 3
58

try this:

import sys
sys.argv = ['arg1', 'arg2']
execfile('abc.py')

Note that when abc.py finishes, control will be returned to the calling program. Note too that abc.py can call quit() if indeed finished.

Jules
  • 14,200
  • 13
  • 56
  • 101
buggywhip
  • 704
  • 5
  • 5
  • Nothing is being passed to `abc.py` as far as I can tell, nor can I see why it should. – geotheory Nov 25 '14 at 15:39
  • 8
    When my 'abc.py' has `argparse` to parse input arguments, I got an error with this method: too few arguments. I ran `python abc.py arg1 arg2` in terminal (this method works without an error) and then printed the content of `sys.argv` by printing and found that `sys.argv` contains the name `'abc.py'` as the first element of the list. Actually, **user2757262's code below** with `sys.argv = ['abc.py','arg1', 'arg2']` was the one that worked! – Kouichi C. Nakamura Apr 08 '15 at 03:41
  • 5
    [The documentation](https://docs.python.org/2.7/library/sys.html#sys.argv) also says, "`argv[0]` is the script name" . – Kouichi C. Nakamura Apr 08 '15 at 06:34
  • @AntiEarth: There being but one `sys` in a process, it will find what you put there. – Davis Herring Apr 03 '19 at 03:11
  • @KouichiC.Nakamura I see that ```execfile``` is removed from Python3. How can I use ```exec``` with arguments? – Bogota May 14 '20 at 07:01
58

execfile runs a Python file, but by loading it, not as a script. You can only pass in variable bindings, not arguments.

If you want to run a program from within Python, use subprocess.call. E.g.

import subprocess
subprocess.call(['./abc.py', arg1, arg2])
thlik
  • 401
  • 6
  • 12
Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • 8
    The following format works for me: `subprocess.call("python abc.py 'arg1'", shell=True)` – geotheory Nov 25 '14 at 15:46
  • 2
    @geotheory Sure that works, but it's less safe and it gets hairy when you want to pass strings with quotes in them to a subprocess. – Fred Foo Nov 26 '14 at 15:53
  • 4
    Can you explain what do you mean with "loading it, not as a script"? What's the difference? – marco Dec 05 '16 at 22:01
  • 2
    @marco: The idea is that a “script” would be a separate process with its own command line. `execfile` runs in the current process, so (if it’s relevant) uses the *current* command line. In that sense, you can’t use it *without* “passing” arguments! – Davis Herring Apr 03 '19 at 03:17
30
import sys
import subprocess

subprocess.call([sys.executable, 'abc.py', 'argument1', 'argument2'])
nosklo
  • 217,122
  • 57
  • 293
  • 297
13

For more interesting scenarios, you could also look at the runpy module. Since python 2.7, it has the run_path function. E.g:

import runpy
import sys

# argv[0] will be replaced by runpy
# You could also skip this if you get sys.argv populated
# via other means
sys.argv = ['', 'arg1' 'arg2']
runpy.run_path('./abc.py', run_name='__main__')
petre
  • 1,485
  • 14
  • 24
12

You're confusing loading a module into the current interpreter process and calling a Python script externally.

The former can be done by importing the file you're interested in. execfile is similar to importing but it simply evaluates the file rather than creates a module out of it. Similar to "sourcing" in a shell script.

The latter can be done using the subprocess module. You spawn off another instance of the interpreter and pass whatever parameters you want to that. This is similar to shelling out in a shell script using backticks.

Noufal Ibrahim
  • 71,383
  • 13
  • 135
  • 169
5

You can't pass command line arguments with execfile(). Look at subprocess instead.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
2

If you set PYTHONINSPECT in the python file you want to execute

[repl.py]

import os
import sys
from time import time 
os.environ['PYTHONINSPECT'] = 'True'
t=time()
argv=sys.argv[1:len(sys.argv)]

there is no need to use execfile, and you can directly run the file with arguments as usual in the shell:

python repl.py one two 3
>>> t
1513989378.880822
>>> argv
['one', 'two', '3']
loretoparisi
  • 15,724
  • 11
  • 102
  • 146
  • 1
    This goes without saying for some users, but you can use the above approach on variables that were defined/used within functions by adding those variables to the global namespace inside the function. – Brian Bartoldson Jan 15 '19 at 21:47
2

If you want to run the scripts in parallel and give them different arguments you can do like below.

import os
os.system("python script.py arg1 arg2 & python script.py arg11 arg22")
Mehmet nuri
  • 840
  • 7
  • 7
  • Please don’t recommend `os.system`—its legitimate use cases are *very* rare. – Davis Herring Apr 03 '19 at 03:13
  • Why is it illegitimate @DavisHerring? This comment isn't helpful to future readers who may want to know why Mehmet's solution is unsuitable. – Lou Oct 12 '20 at 08:43
  • @Lou: That doesn't fit in a comment. I was surprised that I couldn't find one to link here, so I [asked/answered my own](https://stackoverflow.com/q/64329284/8586227). – Davis Herring Oct 13 '20 at 05:51
1

Besides subprocess.call, you can also use subprocess.Popen. Like the following

subprocess.Popen(['./script', arg1, arg2])

Anakin Tung
  • 419
  • 5
  • 17
0

This works:

subprocess.call("python abc.py arg1 arg2", shell=True)
amalik2205
  • 3,962
  • 1
  • 15
  • 21
0
runfile('abc.py', ['arg1', 'arg2'])
D.P.
  • 21
  • 4
0

This works for me :

import subprocess
subprocess.call(['python.exe', './abc.py', arg1, arg2])
Enrique Benito Casado
  • 1,914
  • 1
  • 20
  • 40