Home >Backend Development >Python Tutorial >Calling Linux Shell commands under Python
Sometimes it is inevitable to call Shell commands directly to complete some relatively simple operations, such as mounting a file system. So how do we call Linux Shell commands using Python? Here are some commonly used methods:
1. os module
1.1. The exec method family of os module
Python’s exec system method is consistent with Unix’s exec system call. These methods are suitable for calling external programs in the child process, because the external program replaces the code of the current process and does not return. (I read some help(os) --> search "exec" related introduction, but I don't quite understand how to use it)
1.2. The system method of the os module
The system method will create a child process to run externally Programs and methods only return the running results of external programs. This method is more suitable for situations where the external program does not output results.
[python] view plaincopy
>>> import os
>>> os.system("echo "Hello World"") # Directly use os.system to call an echo command
Hello World ——————> Print command results
0 ——————> What's this ? Return value?
>>> val = os.system("ls -al | grep "log" ") #Use val to receive the return value
-rw-r--r-- 1 root root 6030829 Dec 31 15: 14 log ————— & gt; At this time, only the command result was printed
& gt; & gt; & gt; propd value
0 ————— & gt; 0
>>> val = os.system("ls -al | grep "log1" ")
>>> print val os. system calls a command that does not return a result, and the return value is 256~
>>>
Note: As mentioned above, this method will save the results of the external program, that is, the results of os.system, so if If you want to receive the return value of the command, then look down~1.3. The popen method of the os module
This method is very useful when you need to get the output results of an external program. It returns a file-like object and calls the object The read() or readlines() method can read the output content. For example, when using urllib to call Web API, the obtained data needs to be processed. os.popen(cmd) To get the output of the command, just call read() or readlines(), such as a=os.popen(cmd).read()
[python] view plaincopy
& gt; & gt; & gt; os.popen ('ls -lt')#Calling OS.POPEN (CMD) does not get the results we want
& lt; open file 'ls -lt', mode 'at 0xb7585ee8 & gt. ;
>>> print os.popen('ls -lt').read() # Call the read() method to get the result of the command
total 6064
-rwxr-xr-x 1 long long 23 Jan 5 21:00 hello.sh
-rw-r--r-- 1 long 147 Jan 5 20:26 Makefile
drwxr-xr-x 3 long long 4096 Jan 2 19:37 test
-rw-r--r-- 1 root root 6030829 Dec 31 15:14 log
drwxr-xr-x 2 long long 4096 Dec 28 09:36 pip_build_long
drwx------ 2 Debian-gdm Debian-gdm 4096 Dec 23 19:08 pulse-gylJ5EL24GU9
drwx------ 2 long long 4096 Jan 1 1970 orbit-long
>>> val = os.popen('ls -lt').read() #Use variables to receive command return values
>>> if "log" in val: To determine whether there is a string in the return value
... print "Haha, there is the log"
... else:
... print "No,not happy"
...
Haha, there is the log
2. commands module
Use the getoutput method of the commands module. The difference between this method and popend is that popen returns a file-like object, and this method will The output of the external program is returned as a string, which is more convenient to use in many cases.
Main methods:
* commands.getstatusoutput(cmd) Return (status, output)
* commands.getoutput(cmd) Return only the output result
* commands.getstatus(file) Return The execution result string of ls -ld file, getoutput is called, this method is not recommended
[python] view plaincopy
long@zhouyl:/tmp/tests$ python
Python 2.7.3 (default, Jan 2 2013, 16:53:07)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import commands
>>> commands. getstatusoutput('ls -lt') # Return (status, output)
(0, 'total 5900n-rwxr-xr-x 1 long long 23 Jan 5 21:34 hello.shn-rw-r--r-- 1 long long 147 Jan 5 21:34 Makefilen-rw-r--r-- 1 long long 6030829 Jan 5 21:34 log')
>>> commands.getoutput('ls -lt') # Return the output result of the command (it seems to be different from the output format of the Shell command~)
'total 5900n-rwxr-xr-x 1 long long 23 Jan 5 21:34 hello.shn-rw-r--r-- 1 long long 147 Jan 5 21:34 Makefilen-rw-r--r-- 1 long long 6030829 Jan 5 21:34 log'
>>> commands.getstatus('log') # Call com mands.getoutput The command in performs the same operation on the 'log' file
'-rw-r--r-- 1 long long 6030829 Jan 5 21:34 log'
>>> . subprocess module
According to the official Python documentation, the subprocess module is used to replace the above modules. There is a parallel ssh tool implemented in Python - mssh. The code is very short, but very interesting. It calls subprocess in the thread to start the subprocess to do the work.
[python] view plaincopy
>>> from subprocess import call
>>> call(["ls", "-l"])
The advantage of subprocess compared to system is that it is more flexible (you can get standard output, standard error, "real" status code , better error handling, etc..). I think using os.system is obsolete, or will soon be.
4. Comparison and summary of various methods
4.1. About os.system
os.system("some_command with args") passes the command and parameters to your system shell, which is good because you can Use this method to run multiple commands simultaneously and set up pipes and input and output redirection. For example:
os.system("some_command < input_file | another_command > output_file")
However, although this is convenient, you need to manually handle the escaping of shell characters, such as spaces, etc. Additionally, this only allows you to run simple shell commands and not external programs.
4.2. About os.popen
Using stream = os.popen("some_command with args") can also do the same thing as os.system. The difference from os.system is that os.popen will return a class File object, use it to access standard input and output.
4.3. About subprocess.popen
The Popen class of the subprocess module is intended to be a replacement for os.popen, but because it is very comprehensive, it is slightly more complicated than os.popen.
For example, you can use print Popen("echo Hello World", stdout=PIPE, shell=True).stdout.read() instead of print os.popen("echo Hello World").read(). But in comparison, it is good to use a unified class including 4 different popen functions.
4.4. About subprocess.call
The call function of the subprocess module. It's basically like the Popen class and takes the same parameters, but it simply waits for the command to complete and gives you a return code. For example:
return_code = subprocess.call("echo Hello World", shell=True)
There are also fork/exec/spawn functions like in C in the os module, but I do not recommend using them directly. subprocess may be more suitable for you.
==============================================
[1] http://demi-panda.com/2013/01/25/python-shell-command/index.html
[2] http://m.blog.csdn.net/blog/overstack/9295995
[3] http://blog.csdn.net/swiftshow/article/details/7755543
The following is the official Python documentation for the content involved in the article:
[4] http://docs.python.org/library/subprocess .html#replacing-older-functions-with-the-subprocess-module -- About using subprocess to replace the old method
[5] http://docs.python.org/lib/os-process.html -- os The exec method family and the system method
[6] http://docs.python.org/lib/os-newstreams.html -- the popen method of os
[7] http://docs.python.org/ lib/node528.html -- Introduction to os subprocess