In this article, you’ll learn three ways to execute Python and non-Python programs from within a Python program.
Method 1: Execute a File with Subprocess
Challenge: In Python, sometimes you need to execute another file, script, or program from within your own Python program and provide arguments.
There are a number of ways to do this, but I find the most straightforward to be with the “subprocess” import.
import subprocess subprocess.run(['git', 'commit', '-m', 'Testing commits with Automation!'])
Let’s break down exactly what this means. The subprocess.run()
function resides within the subprocess module of the standard Python library. It isn’t loaded by Python by default, but is additional functionality that must be imported. Once that code is imported into your Python script, it can be called. This module replaces older functions like os.spawn()
and os.system()
.
At a minimum, the subprocess.run()
function needs to be passed a list that includes the file or command to be executed with each argument as a separate element of the list. In this case, the command we’re running is git commit -m 'Testing commits with Automation!'
, and it will run as a subprocess of the Python interpreter.
Sometimes, command line arguments can be complex and building out the list of arguments isn’t easy. I recommend playing around with the shlex
library in an interactive terminal until you get a hang of it. You won’t need this in your production code, but might help make the concept more clear.
>>> import shlex >>> shlex.split("git commit -m 'Testing commits with Automation!'") ['git', 'commit', '-m', 'Testing commits with Automation!']
“`
If after following these steps you’re still struggling to get your command to execute, consider the following: using the full path of the file to be executed (e.g. /home/user/script.py
or C:\Program Files\Python 3.9\python.exe
), checking the permissions of the file you are attempting to execute to ensure it is in fact executable, checking for typos or case sensitivity.
In summary, the steps to execute a file with arguments from within a Python script are:
- Import the
subprocess
module - Prepare your command line arguments in list format
- The
shlex
module can assist with parsing complex command lines
- The
- Make a call to the function
subprocess.run()
and pass it the argument list as a parameter
There is a lot of useful functionality in the subprocess library, so I recommend checking out the official documentation. One common additional use case would be capturing the data returned to stdout
. Fortunately, Python makes this easy. All that is needed is an additional parameter, capture_output=True
, to the subprocess.run()
function call included after the list of arguments. Like this –
output = subprocess.run(["ls", "-l"], capture_output=True) print(output.stdout)
In the example above, the directory listing generated by the ls -l
command will store the text returned by stdout within output.stdout
. The print command will display that output on screen. Capturing the output of executed subprocesses will allow you to incorporate that feedback into your program. For example, if your code is creating a directory for a user, you now can check to see if that directory already exists before trying to create it again!
Now that we’ve covered how to execute a file with arguments, how can we create a Python script for ourselves that handles command line arguments?
Method 2: Execute a Python File with Arguments Using sys.argv
In order to pass arguments to your Python script, you will need to import the sys
module. Once this module is imported in your code, upon execution sys.argv
will exist, containing a list of all of the arguments passed to your script.
Consider the following script:
import sys print(len(sys.argv)) print(sys.argv)
If we run this script from a command prompt with python3 args.py arg1 arg2
, it will return:
3 ['args.py', 'arg1', 'arg2']
If this script is already executable (and we include the #! /usr/bin/python3
line up top), we could execute it like this ./args.py arg1 arg2
and it will return:
3 [‘./args.py’, ‘arg1’, ‘arg2’]
Notice that even though only two arguments were provided to the script, three arguments are listed. Element 0 of the list is always the name of the script itself. If the user renames the script on their endpoint, sys.argv[0]
will reflect that name.
Often, when writing a program in Python it is important to know how many arguments are passed to the script for the purposes of error checking. If insufficient parameters are supplied by the user, a helpful error message giving usage instructions could be provided.
Consider the following code:
import sys if len(sys.argv) == 1: print("Usage: %s -f" % sys.argv[0]) exit() for argument in sys.argv: if argument == "-f": print("Hello Finxter!")
This code block will check to see if at least one argument is passed to the program, and if not, it will print a helpful error message. Then it will iterate through the list of arguments checking for “-f”
. If that argument was passed, the program will print our “Hello Finxter!”
message!
This is the rough and rudimentary way of processing command line arguments. In summary:
- Import the
sys
module - Access the arguments at the defined index, for example
sys.argv[1]
- A for loop may assist you if your users place arguments out of order
Another thing to consider is that Python also has a module named argparse that allows us to do more with command line arguments in a more readable way, as well as easily handle optional and positional parameters.
Now that you know how to incorporate command line arguments into your script, how do you use them if you’re using an IDE like PyCharm?
Method 3: Execute a Python File with Arguments in PyCharm
Inside of the PyCharm development environment, the top toolbar will include a Run tab. Click on it and choose “Edit Configurations”. A new window will pop up that will allow you to enter in the necessary parameters to execute your script.
This works identically to passing arguments via the command line.
Thanks for reading! Be sure to check out the rest of our tutorials on https://blog.finxter.com/.