上一篇文章已经介绍了python如何调用linux命令行执行命令,本文将主要介绍如何在python脚本中获取linux命令行命令的输出(与上一篇文章所提到的模块几乎是相同的)。
linux是系统,而python则只是一种编程语言,很多时候需要使用到linux的命令行来执行某些功能或者运行某些软件。而有时候我们需要知道软件执行的成功与否或者需要获取命令在命令行中的输出,这些输出可能会作为python中的新变量。上面描述的情况对我来说是比较常见的,因此我将简要介绍如何在python中获取linux命令行在终端的输出内容。
常见的使用python获取linux shell命令行命令的执行结果的方式大致有使用os模块和subprocess模块两种方式。
-
os模块
-
subprocess模块
-
首先要介绍的还是更为常用的os模块,上一篇文章讲过os.system()和os.popen()都能够调用命令行执行命令,但os.system()的返回值为命令退出状态码,os.popen()得到的返回值则是文件对象,可以使用例如read()、readline()、readlines()等命令进行读取。
os.system
:
>>> import os
>>> a = os.system('ls | wc -l')
15 # 运行命令的结果,由于在终端,因此直接打印出来了,获取命令行的输出有时候就是获取15这样的内容。
>>> print(a)
0 # 退出状态码,为0时是正常执行。
>>> b = os.system('lsk') # 这里随便输了一个错误的命令
sh: 1: lsk: not found # 终端显示没有这个命令,也可以看出这时候使用的shell为sh
>>> print(b)
32512 # 退出状态码为32512,应该是一个代表发生错误的状态码
os.popen
>>> import os
>>> a = os.popen('ls')
>>> print(a.readlines())
['bin\n', 'etc\n', 'ete3\n', 'include\n', 'lib\n', 'share\n']
# 得到的结果为文件对象,使用readlines()将其变为列表,
# 之后可以将这些内容用于python后续的操作。
>>> b = os.popen('lsk')
>>> /bin/sh: 1: lsk: not found # 提示命令出错
>>> print(b.read())
# 未输出结果,表明错误信息不会被python捕捉
subprocess译为子进程,这个模块现在才是王者级的存在,其功能很丰富,上篇文章也提到了subprocess模块的各种方法如run、call、Popen、check_output等使用方式类似,最主要的区别在于它们的返回值不同。接下来将介绍每种方法的返回值。
此方法上篇文章已介绍过,其返回值为一个CompletedProcess的类实例,这个类实例返回时会带上返回的状态和最开始传入的参数。直接拷贝上篇文章的内容:
>>> import subprocess
>>> a = subprocess.run('ls -h -a', shell = True)
. .. bin etc ete3 include lib share
# ls -h -a查看当前目录下的所有文件及文件夹
# 这里如果shell为False会报错
>>> print(a)
CompletedProcess(args='ls -h -a', returncode=0)
# 运行结果a为类实例,可以看到返回状态和参数
subprocess.call()与os.system()类似,两个方法都是返回命令执行的退出状态,subprocess.call()执行的效果:
>>> import subprocess
>>> a = subprocess.call('ls')
bin etc ete3 include lib share
>>> print(a)
# 成功运行的退出码
>>> b = subprocess.call('lsk', shell=True)
/bin/sh: 1: lsk: not found
# 这里需要使用到shell=True调用shell,否则会报错而直接停止运行。
>>> print(b)
# 错误运行的退出码
在某些情况下可能会使用到这些退出码来判断命令是否正常运行了。
Popen为subprocess类底层调用的方法,Popen类还支持很多的方法如Popen.wait()、Popen.poll()、communicate()、Popen.terminate()等很多的方法,还可以通过如Popen.args、Popen.stdin、Popen.stdout、Popen.stderr等查看某些参数、管道内容或者某些输出,因此使用灵活性更强。
看一个使用Popen的简单的例子吧:
>>> import subprocess
>>> a = subprocess.Popen('ls', stdout = subprocess.PIPE, stderr = subprocess.PIPE)
# 这里将输出和错误和都交给subprocess的管道
>>> print(a)
<subprocess.Popen object at 0x7f3a19987940>
# 得到的返回值a为一个Popen类的类实例
>>> a.communicate()
(b'bin\netc\nete3\ninclude\nlib\nshare\n', b'')
# 通过communicate方法获取输出(标准输出和错误),得到了一个元组,其中的元素都是二进制形式的
# 第一个元素为标准输出,第二个元素为错误信息
>>> a.communicate()[0].decode()
'bin\netc\nete3\ninclude\nlib\nshare\n'
# 使用decode方法对二进制结果进行解码,得到的为ls的结果(虽说混到了一起)
>>> a.communicate()[1].decode()
# 对标准错误进行解码无结果,这是因为命令正确执行了并未出错
这个命令看名字就清楚了,它就是获取命令行命令执行结果的一条很明显的命令,其使用方式也与上面几乎相同,但其得到的结果也是二进制形式,需要通过decode进行解码。
>>> import subprocess
>>> a = subprocess.check_output('ls')
>>> print(a)
b'bin\netc\nete3\ninclude\nlib\nshare\n'
>>> a.decode()
'bin\netc\nete3\ninclude\nlib\nshare\n'
# 不多解释
这个命令返回值为退出状态码和标准输出组成的元组,即(exitcode, output)。
>>> import subprocess
>>> a = subprocess.getstatusoutput('ls')
(0, 'bin\netc\nete3\ninclude\nlib\nshare')
>>> a[1]
'bin\netc\nete3\ninclude\nlib\nshare'
# 不多解释
本文已介绍平常可能会用上的subprocess方法,还有一些其它的方法可能不太会用上,读者若有兴趣也可以自行探索一下。不管使用什么subprocess方法,使用到的参数几乎都相似,使用的方式也都类似,因此多举一反三即可。
本文与上篇文章相辅相成,希望能在python和linux联动使用的过程中帮助到大家。
参考:https://docs.python.org/zh-cn/3/library/subprocess.html#security-considerations
参考:https://blog.csdn.net/gymaisyl/article/details/90746983
在Python中执行Shell命令并获取其结果,通常可以使用subprocess模块。这个模块允许我们启动新的进程,连接到它们的输入/输出/错误管道,并获取它们的返回码。下面是一个详细的示例,展示了如何使用subprocess.run()函数来执行Shell命令并获取其输出。
1. 示例一:使用subprocess.run()执行ls命令并获取结果
这个示例将执行ls命令(在Unix/Linux...
Shell调用Python函数
Shell脚本调用Python函数,本例子是通过Shell调用Python脚本,检查服务器上的某端口是否开启,编写的Python脚本port.py,脚本内容:
#!/usr/bin/python
# port.py
import socket
def scan(port):
s = socket.socket()
s.settimeout(...
在 Linux 下,不管你是启动一个桌面程序也好,还是在控制台下运行命令,所有的程序在结束时,都会返回一个数字值,这个值叫做返回值,或者称为错误号 ( Error Number )。
在控制台下,有一个特殊的环境变量 $?,保存着前一个程序的返回值,我们可以试试:
$ ls *.png
Diagram1.png eqn.png pe
os.popen(“xxx”).readlines()
执行并获取全部的执行结果,获取结果为list,每行内容为list的一个值。需要具体哪一行内容可直接list[0]提取
(推荐使用,其实通过ctrl可以看到popen方法源码底层就是subprocess.Po...
def run_command(command):
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
output, error = process.communicate()
return output.decode('utf-8').strip(), error.decode('utf-8').strip()
这个函数接受一个字符串参数,即要执行的shell命令。它使用subprocess.Popen函数启动一个新的进程来执行命令,并将stdout和stderr流重定向到PIPE管道。然后使用communicate函数等待进程结束并读取输出和错误流。最后将结果转换为字符串并返回。注意,这个函数使用了shell=True参数,这意味着传递给它的命令可以包含shell语法(例如管道、重定向等)。如果你不需要这种功能,可以将shell参数设置为False,这将更安全一些。
报错BLAST Database error: No alias or index file found for nucleotide database[db] in search path的可能原因
sen233333:
python 类的使用(5)之类装饰器(类的装饰器和类作为装饰器)
qq_41339054: