Python Tutorial: Calling External Commands Using the Subprocess Module

Corey Schafer · Beginner ·🛠️ AI Tools & Apps ·6y ago

Key Takeaways

This video tutorial demonstrates how to use the subprocess module in Python to call external commands, capture output, and handle errors, with examples of running commands with and without the shell argument, piping output, and redirecting errors.

Full Transcript

hey there how's it going everybody in this video we're going to be learning how to call external commands using Python with the sub process module so there are many scenarios where you might want to call an external program using Python and if you need to then you can also capture the output of those commands or even pipe the output from one command into another so that's what we're going to be learning to do in this video using the sub process module so let's go ahead and get started so I have a blank Python module open here and first we're going to want to import the sub process module so let's just say import sub process okay so now in order to run an external command this is extremely simple we'll look at how to do some more complicated stuff in a bit but to simply run a command we can just say sub process dot run and then run the command that we run a run so I'll do LS now just that heads up I'm on a Mac so I'm going to be using Linux commands in this video but you can use these same processes to run Windows commands as well so LS the command that I just ran here it will list the files and folders in the current directory and again that's a Linux command on Windows you have to use Windows commands so the LS equivalent on Windows is derp so di are whoops sorry dir so if I save this and run it then we can see that the LS command printed out everything in the current directory now if you're on Windows and tried to run the dir command or something similar then you might have got an error at this point that the system could not find the file specified so the reason is because the dir command is built into the shell so we'd have to pass in an argument of shell equals true so if you're on Windows then you could say pass in an extra argument here of shell is equal to true and if we run that you can we can see here at that on Mac we get the same result but on Windows that should prevent you from getting that error and also if we set the show argument to true then we can just pass in an entire command as a string so if I wanted to add more arguments to my external command then I could say so for example some arguments I could add to LS would be - L a so if I run this then now we can see that runs that LS command with those additional arguments and those additional arguments just provide more information here now if you are using this shell equals true then that can be a security hazard if you're using untrusted input so only use that if you're passing in the arguments yourself and be sure you're not running it with user input or anything like that but if you're not using the shell argument then we actually can't pass in the entire command as a string like we did here instead we need to pass in everything as a list of arguments so if we wanted to run this same command without the shell arguments set to true then we would have to say so let me get rid of the shell argument here so I could just pass this in as a list and I'm gonna have to do this as a list so our first item here is going to be the command LS the second item here is the arguments so now if I run that then we can see that we get the same thing okay so we can see that all we're doing right now is running this sub process dot run method and it's printing out the results just like we'd print something in a Python script now the reason is that we're not capturing that standard out the standard out just goes wherever the standard out of the script normally goes which is in the console here so let's try to capture this into a variable instead now you might try to do this just by saying something like p1 is equal to sub process dot run but if I run that then we can see that it's still printing the standard out here to the console but also let's see if we get anything within that p1 variable so if I print out p1 and run that then we can see that after our LS output here down here where we printed that p1 variable that comes out as a completed process object now if you want to see what all we can do with a completed process object then you can run help on that but let's just go over a few of those really quick so first we can check the arguments that were passed into the original command and we can do that by printing out p1 dot orgs so if I save that and run it then we can see that we have the arguments that we passed into that original command here we can also check the return code and the return code will show us whether we got any errors or not so if I print out P 1 dot return code if I run that then we can see that we got a return code of 0 and that means that it ran successfully now a way that I like to remember that is to think of that as meaning zero errors now we can also grab the standard out as well so let's grab that if I print out p1 dot STD out and run that okay so when we print it out that standard out we can see that we got none and that might be a little surprising to some people so we got a result of none but really what we want is the output from the external command that we ran so the reason that it's printing none is because like I said before it's just sending the standard out to the console all of this stuff here so we want to capture that instead so to capture that we can just pass in another argument here and we can pass in an argument of capture underscore output is equal to true and if I spell that correctly if I save that and run it and actually first we can see that we did get something here first let me comment out the print statement we're printing the p1 standard out and if I save that and run it then you can see that now we're not getting anything in the Python console here so it's no longer outputting that just by running this sub process dot run command so now it actually is capturing it in this p1 variable so now when we actually print out p1 dot standard out if I run that then we can see now it's captured there now one thing to notice here is that the standard out was captured as bytes so it doesn't look like it did before with all those new lines so if we want the new lines to actually be spaced out then we'll have to convert this to a string now there are a couple different ways that we could do this first we could just decode those bytes by saying p1 dot standard out dot decode run the decode method on that if I run that then we can see that it looks like it did before now I've never done a video on Unicode and bytes versus strings and encoding and decoding and all of that that's a tutorial that I'd like to put together in the near future but in this case when we decode those bytes it's converting it into a string now if we don't want to use decode then we can just get rid of that and pass in an argument to the run method saying that we want text instead so I'm going to remove the decode method there and I'm just going to pass in an additional argument of text equals true so now if I run that we can see that we're not decoding the standard out but it comes in as a string anyway so that's good okay so when we set that argument of capture output equal to true what that's actually doing in the background is setting the standard out and the standard error to the sub process pipe and that allows us to capture those values so let me show you what it would look like to set that standard out argument directly so instead of saying capture output is equal to true here instead I'm going to say STD out is equal to and that is sub process dot pipe and again that's actually what setting capture output equal to true does in the background but it also redirects the standard error to that pipe as well but just setting the standard out equal to that sub process pipe we should be able to run what we have here and get the same result so if I run this then we can see we got the same results that we did before now we can also redirect the standardout to other places as well so for example let's say that we wanted to redirect that to a file instead that could be used for logging or anything like that now in order to do that we could simply just open up a file and redirect it to there so I can say with open and I will just open a file here called output dot txt and I want to open that in write mode and I'll just open that as F now let me indent this so that's within our context manager there and now for our standard route instead of redirecting to this sub process pipe and said I'm just going to redirect that to F our file and I'm going to remove our print statement there because we don't need that because we're not capturing that using that sub process pipe anymore so now if I run this it doesn't look like we got anything but if I open up my sidebar here we can see that now I have this output txt if I open that up then we can see that we got the results from that command in our output txt file so that did work okay so I wanted to show how we could redirect that to a file but now let's go back to what we had before where we're just capturing that output in a variable so I'm just going to get rid of all that file stuff and instead I'm just going to set this back equal to capture underscore output and set this equal to true okay so now let's take a look at a couple of different things that can happen if our command isn't successful so let's see what happens when we get an error so I'm going to change my command here to instead try to list the contents of a directory that doesn't exist so I'm just going to add a another argument here and I'm just going to add this to a bonus directory I'll just say dne for does not exist and this argument that LS command is going to try to list the contents of this that doesn't exist so if I run this then we can see that we don't get any output and that's because we captured it here now one thing that might surprise some people is that we don't get an error within Python some people might expect Python to throw an exception if the external command fails but it doesn't do that instead it just returns a nonzero error code so again we can check that just by printing out p1 dot return code and we saw this before so if I run that then before that was 0 but now it is 1 which means we got an error and if we want to see that error then we can print that out as well by saying stderr for standard error if I run that we can see that the error that that command got was LS DNA no such file or directory because that directory doesn't exist so within your script if you only wanted to proceed if that command was successful then you could put in a conditional if you wanted to so something like if p1 dot return code is not equal to zero then that would be your error case or equal equals zero for it not having any errors now if you did want Python to throw an exception if the external command fails then we can just pass in an argument of check equals to true so if I add in an additional argument here I'm going to say check is equal to true and now if I run this then we can see that now Python throws an exception here and we got a trace back and it says that our command returned a non zero exit status of one so that might be useful depending on whether or not you actually want Python to throw an exception if your command actually fails or returns a non zero status code now another common thing to do with errors is to just ignore them by redirecting them to something called dev null and redirecting them to dev null just means that you are ignoring those so we can do this with the sub process similar to how we've redirected standard out using the pipe so we can replace our capture output here and instead before we did STD out this time I'm going to do stderr for standard error and we're going to redirect that to sub process dot de Vie in you ll Dev null and that's all caps so now if we save that and run it oops and I'm actually getting a trace back here still because we still have check is equal to true so I'm just gonna get rid of check also I don't need text either so I'm just going to delete both of those okay so now we're redirecting that to dev null if I save that and run it we can see that it just redirected our error so we don't have a standard error here it just says none okay so so far we've been looking at how to capture output and errors but we can actually change the input that different commands receive as well so for example let's say that we wanted to take the output from one command and have that be the input to another so let's look at an example of this so for the first command I'm just gonna run a cat on a file which is a linux command that will just print the contents of a file if it just has one file as the input and for the second command I'm going to use the output of that first command to grab that file and grep can be used to search the file for certain contents and again these are Linux commands since I'm on a Mac but you should be able to do something similar to this using different windows commands as well okay so first I'm going to run the cat command on a file that I have in the same directory here called test dot txt and I actually have test exe open here and sublime so let's take a quick look at this so we can see that this is just a very simple file with seven lines that says this is a test with seven lines okay so in order to run the cat command on that file I'm going to change this up a bit so instead of LS I'm going to run cat and I want to run cat on that test dot txt file in the same directory I don't have any more arguments after that and I don't want to redirect standard error to Dev null instead I'm just going to set capture output equal to true so that we can get that output and any errors okay so to see if that worked then I'm just going to print out our standard out so if I save that and run it then we can see that we got the contents of that file it's in bytes right now so I forgot to add text is equal to true to make that a string so I'll save that and run it and now we can see that we got the same contents of that file okay so now in order to use that output as the input of the grep command I'm going to copy what we have here previously and I'm just going to change this a little bit so let me paste this and now I'm going to change this to be p2 as our variable and now I want to run grep and I am going to do a couple of different arguments here so I'm going to also pass in an argument of - in which gives us the line number that it finds a match just so we can test this and let's look back at our test txt I will search for the text of test and that's on line four so I will pass in a test for the word that we are searching for okay so I'm also going to keep capture output equal to true and text equal to true but I'm also going to add one last argument here and I'm going to say input is equal to and I want this input to be equal to p1 dot standard out so if I save that I'm going to comment out the print statement on the p1 standard out there so we're just passing that in as the input for that grep command and if I print out P 2 dot standard out and run this then we can see that grep says that it found test on line four of that output from the first command now that's a bit of a contrived example because you can just grab files directly but it might be useful if you want to capture the output of this command first and do some type of processing on it and then pass that into the grep command so it's definitely useful to know how to do this at times because it's nice being able to grab that output from step to step but if you're not doing anything with the output between the steps then you can definitely just use that shell argument that we saw earlier and just write out the whole command using pipes and Linux if you're comfortable doing that instead so what I mean by that is that you could you know instead of doing this whole process here we could just say shell is equal to true and then instead of passing this in as a list of arguments we could just say cat test oops I got to get rid of that square bracket as well we could just pass all of this in as a string and then do a grep - in test and if I print out the standard out of that then we can see that we got the same result but like I was saying it's definitely useful to know how to pass in the input to different external commands because you know if you are doing step-by-step processing and doing some string parsing or something like that using Python then you can pass in those results into a different command so that's definitely useful okay so I think that's going to do it for this video I hope that you found it useful learning how you can call external commands using Python and also how to redirect those outputs and inputs and things like that it's definitely useful especially when I'm writing scripts on a web server or something like that it makes it possible to run some background commands within the Python script itself and process that that output further if need be but if anyone has any questions about what we covered in this video then feel free to ask in the comment section below and I'll do my best to answer those and if you enjoy these tutorials and would like to support them then there are several ways you can do that the easiest way is to simply like the video and give it a thumbs up and also it's a huge help to share these videos with anyone who you think would find them useful and if you have the means you can contribute through patreon and there's a link to that page in a description section below be sure to subscribe for future videos and thank you all for watching

Original Description

In this Python Programming Tutorial, we will be learning how to run external commands using the subprocess module from the standard library. We will learn how to run commands, capture the output, handle errors, and also how to pipe output into other commands. Let's get started... ✅ Support My Channel Through Patreon: https://www.patreon.com/coreyms ✅ Become a Channel Member: https://www.youtube.com/channel/UCCezIgC97PvUuR4_gbFUs5g/join ✅ One-Time Contribution Through PayPal: https://goo.gl/649HFY ✅ Cryptocurrency Donations: Bitcoin Wallet - 3MPH8oY2EAgbLVy7RBMinwcBntggi7qeG3 Ethereum Wallet - 0x151649418616068fB46C3598083817101d3bCD33 Litecoin Wallet - MPvEBY5fxGkmPQgocfJbxP6EmTo5UUXMot ✅ Corey's Public Amazon Wishlist http://a.co/inIyro1 ✅ Equipment I Use and Books I Recommend: https://www.amazon.com/shop/coreyschafer ▶️ You Can Find Me On: My Website - http://coreyms.com/ My Second Channel - https://www.youtube.com/c/coreymschafer Facebook - https://www.facebook.com/CoreyMSchafer Twitter - https://twitter.com/CoreyMSchafer Instagram - https://www.instagram.com/coreymschafer/ #Python
Watch on YouTube ↗ (saves to browser)
Sign in to unlock AI tutor explanation · ⚡30

Playlist

Uploads from Corey Schafer · Corey Schafer · 0 of 60

← Previous Next →
1 Web fonts using CSS Font Face
Web fonts using CSS Font Face
Corey Schafer
2 Using Font Awesome in Desktop Applications (OS X)
Using Font Awesome in Desktop Applications (OS X)
Corey Schafer
3 Sublime Text 2: Setup, Package Control, and Settings
Sublime Text 2: Setup, Package Control, and Settings
Corey Schafer
4 ArcGIS API for JavaScript Part 1: Our First Web Map
ArcGIS API for JavaScript Part 1: Our First Web Map
Corey Schafer
5 Mac Tip: Windows' Snapping Feature on Mac with HyperDock
Mac Tip: Windows' Snapping Feature on Mac with HyperDock
Corey Schafer
6 Linux/Mac Terminal Tutorial: Creating Aliases for Commands
Linux/Mac Terminal Tutorial: Creating Aliases for Commands
Corey Schafer
7 ArcGIS API for JavaScript Part 2: Starting Templates
ArcGIS API for JavaScript Part 2: Starting Templates
Corey Schafer
8 Paver Patio Time Lapse
Paver Patio Time Lapse
Corey Schafer
9 Mac Tip: Ways to perform Screen Capturing and Screenshots
Mac Tip: Ways to perform Screen Capturing and Screenshots
Corey Schafer
10 WordPress Plugins: Imsanity
WordPress Plugins: Imsanity
Corey Schafer
11 WordPress Tips: Test your theme with Theme Unit Test and Monster Widget
WordPress Tips: Test your theme with Theme Unit Test and Monster Widget
Corey Schafer
12 Sublime Text 3: Setup, Package Control, and Settings
Sublime Text 3: Setup, Package Control, and Settings
Corey Schafer
13 Understanding Binary, Hexadecimal, Decimal (Base-10), and more
Understanding Binary, Hexadecimal, Decimal (Base-10), and more
Corey Schafer
14 Mac Tip: Adding Folder Stacks to the Dock
Mac Tip: Adding Folder Stacks to the Dock
Corey Schafer
15 CSS Tips and Tricks: Add External URLs to Print Stylesheets
CSS Tips and Tricks: Add External URLs to Print Stylesheets
Corey Schafer
16 JavaScript Arrays: Properties, Methods, and Manipulation (Part 7 of 7)
JavaScript Arrays: Properties, Methods, and Manipulation (Part 7 of 7)
Corey Schafer
17 JavaScript Arrays: Properties, Methods, and Manipulation (Part 1 of 7)
JavaScript Arrays: Properties, Methods, and Manipulation (Part 1 of 7)
Corey Schafer
18 JavaScript Arrays: Properties, Methods, and Manipulation (Part 5 of 7)
JavaScript Arrays: Properties, Methods, and Manipulation (Part 5 of 7)
Corey Schafer
19 JavaScript Arrays: Properties, Methods, and Manipulation (Part 4 of 7)
JavaScript Arrays: Properties, Methods, and Manipulation (Part 4 of 7)
Corey Schafer
20 JavaScript Arrays: Properties, Methods, and Manipulation (Part 3 of 7)
JavaScript Arrays: Properties, Methods, and Manipulation (Part 3 of 7)
Corey Schafer
21 JavaScript Arrays: Properties, Methods, and Manipulation (Part 2 of 7)
JavaScript Arrays: Properties, Methods, and Manipulation (Part 2 of 7)
Corey Schafer
22 JavaScript Arrays: Properties, Methods, and Manipulation (Part 6 of 7)
JavaScript Arrays: Properties, Methods, and Manipulation (Part 6 of 7)
Corey Schafer
23 Python Tutorial: if __name__ == '__main__'
Python Tutorial: if __name__ == '__main__'
Corey Schafer
24 Sublime Text Quick Tip: "Go To Definition" Click Shortcut
Sublime Text Quick Tip: "Go To Definition" Click Shortcut
Corey Schafer
25 How to quickly create favicons for the desktop, Apple/Android devices, tablets, and more
How to quickly create favicons for the desktop, Apple/Android devices, tablets, and more
Corey Schafer
26 Easily Resize Multiple Images Using Picasa
Easily Resize Multiple Images Using Picasa
Corey Schafer
27 Easily Resize Multiple Images Using the Mac Terminal
Easily Resize Multiple Images Using the Mac Terminal
Corey Schafer
28 Python Tutorial: virtualenv and why you should use virtual environments
Python Tutorial: virtualenv and why you should use virtual environments
Corey Schafer
29 Python Tutorial: pip - An in-depth look at the package management system
Python Tutorial: pip - An in-depth look at the package management system
Corey Schafer
30 Git Tutorial: Using the Stash Command
Git Tutorial: Using the Stash Command
Corey Schafer
31 How Software Engineers, Developers, and Designers can volunteer their skills
How Software Engineers, Developers, and Designers can volunteer their skills
Corey Schafer
32 Git Tutorial: Diff and Merge Tools
Git Tutorial: Diff and Merge Tools
Corey Schafer
33 Git Tutorial: Change DiffMerge Font-Size on Mac OSX
Git Tutorial: Change DiffMerge Font-Size on Mac OSX
Corey Schafer
34 Sublime Text Quick Tip: Launch Sublime Text from the Terminal
Sublime Text Quick Tip: Launch Sublime Text from the Terminal
Corey Schafer
35 Python Tutorial: str() vs repr()
Python Tutorial: str() vs repr()
Corey Schafer
36 Programming Terms: DRY (Don't Repeat Yourself)
Programming Terms: DRY (Don't Repeat Yourself)
Corey Schafer
37 Programming Terms: String Interpolation
Programming Terms: String Interpolation
Corey Schafer
38 Programming Terms: Idempotence
Programming Terms: Idempotence
Corey Schafer
39 Python Tutorial: Namedtuple - When and why should you use namedtuples?
Python Tutorial: Namedtuple - When and why should you use namedtuples?
Corey Schafer
40 Programming Terms: Mutable vs Immutable
Programming Terms: Mutable vs Immutable
Corey Schafer
41 Python Tutorial: Else Clauses on Loops
Python Tutorial: Else Clauses on Loops
Corey Schafer
42 Overview of Online Learning Resources
Overview of Online Learning Resources
Corey Schafer
43 Mac OS X Terminal Tutorial: Time-Saving Keyboard Shortcuts
Mac OS X Terminal Tutorial: Time-Saving Keyboard Shortcuts
Corey Schafer
44 Git Tutorial for Beginners: Command-Line Fundamentals
Git Tutorial for Beginners: Command-Line Fundamentals
Corey Schafer
45 Quickest and Easiest Way to Run a Local Web-Server
Quickest and Easiest Way to Run a Local Web-Server
Corey Schafer
46 Python Tutorial: Generators - How to use them and the benefits you receive
Python Tutorial: Generators - How to use them and the benefits you receive
Corey Schafer
47 Python Tutorial: Comprehensions - How they work and why you should be using them
Python Tutorial: Comprehensions - How they work and why you should be using them
Corey Schafer
48 Chrome Quick Tip: Quickly Bookmark Open Tabs for Later Viewing
Chrome Quick Tip: Quickly Bookmark Open Tabs for Later Viewing
Corey Schafer
49 Programming Terms: Combinations and Permutations
Programming Terms: Combinations and Permutations
Corey Schafer
50 Git Tutorial: Difference between "add -A", "add -u", "add .", and "add *"
Git Tutorial: Difference between "add -A", "add -u", "add .", and "add *"
Corey Schafer
51 Preparing for a Python Interview: 10 Things You Should Know
Preparing for a Python Interview: 10 Things You Should Know
Corey Schafer
52 SQL Tutorial for Beginners 1: Installing PostgreSQL and Creating Your First Database
SQL Tutorial for Beginners 1: Installing PostgreSQL and Creating Your First Database
Corey Schafer
53 SQL Tutorial for Beginners 2: Creating Your First Table
SQL Tutorial for Beginners 2: Creating Your First Table
Corey Schafer
54 SQL Tutorial for Beginners 3: INSERT - Adding Records to Your Database
SQL Tutorial for Beginners 3: INSERT - Adding Records to Your Database
Corey Schafer
55 Linux/Mac Terminal Tutorial: Navigating your Filesystem
Linux/Mac Terminal Tutorial: Navigating your Filesystem
Corey Schafer
56 Python: Ex Machina Easter Egg - Hidden Message within the Code
Python: Ex Machina Easter Egg - Hidden Message within the Code
Corey Schafer
57 Mac Tip: New Split Screen Feature in El Capitan
Mac Tip: New Split Screen Feature in El Capitan
Corey Schafer
58 Setting up a Python Development Environment in Eclipse
Setting up a Python Development Environment in Eclipse
Corey Schafer
59 Git Tutorial: Fixing Common Mistakes and Undoing Bad Commits
Git Tutorial: Fixing Common Mistakes and Undoing Bad Commits
Corey Schafer
60 SQL Tutorial for Beginners 4: SELECT - Retrieving Records from Your Database
SQL Tutorial for Beginners 4: SELECT - Retrieving Records from Your Database
Corey Schafer

This video tutorial teaches how to use the subprocess module in Python to execute external commands and capture their output, with examples of error handling and piping. It provides a comprehensive introduction to using external commands in Python.

Key Takeaways
  1. Import the subprocess module
  2. Run an external command using subprocess.run()
  3. Pass arguments to an external command using subprocess.run()
  4. Capture the standard output of an external command using subprocess.run()
  5. Run an external command with the shell argument set to True
  6. Redirect output to a file using the with open statement
  7. Check the return code of the subprocess
  8. Pass the check argument to subprocess.run to throw an exception if the command fails
💡 The subprocess module provides a powerful way to execute external commands in Python and capture their output, allowing for flexible and efficient automation of system tasks.

Related AI Lessons

Up next
I Asked ChatGPT to Apply to 500 Jobs (8 Interviews in 48 Hours)
Sabrina Ramonov 🍄
Watch →