python之subprocess模块详解

介绍

subprocess是Python 2.4中新增的一个模块,它允许你生成新的进程,连接到它们的 input/output/error 管道,并获取它们的返回(状态)码

这个模块的目的在于替换几个旧的模块和方法。

那么我们到底该用哪个模块、哪个函数来执行命令与系统及系统进行交互呢?下面我们来做个总结:

  • 首先应该知道的是,Python2.4版本引入了subprocess模块用来替换os.system()、os.popen()、os.spawn*()等函数以及commands模块;也就是说如果你使用的是Python 2.4及以上的版本就应该使用subprocess模块了。
  • 如果你的应用使用的Python 2.4以上,但是是Python 3.5以下的版本,Python官方给出的建议是使用subprocess.call()函数。Python 2.5中新增了一个subprocess.check_call()函数,Python 2.7中新增了一个subprocess.check_output()函数,这两个函数也可以按照需求进行使用。
  • 如果你的应用使用的是Python 3.5及以上的版本(目前应该还很少),Python官方给出的建议是尽量使用subprocess.run()函数。
  • 当subprocess.call()、subprocess.check_call()、subprocess.check_output()和subprocess.run()这些高级函数无法满足需求时,我们可以使用subprocess.Popen类来实现我们需要的复杂功能。

 

subprocess模块中的常用函数 

函数

函数描述
subprocess.run()Python 3.5中新增的函数。执行指定的命令,等待命令执行完成后返回一个包含执行结果的CompletedProcess类的实例。
subprocess.call()执行指定的命令,返回命令执行状态,其功能类似于os.system(cmd)。
subprocess.check_call()Python 2.5中新增的函数。 执行指定的命令,如果执行成功则返回状态码,否则抛出异常。其功能等价于subprocess.run(..., check=True)。
subprocess.check_output()Python 2.7中新增的的函数。执行指定的命令,如果执行状态码为0则返回命令执行结果,否则抛出异常。
subprocess.getoutput(cmd)接收字符串格式的命令,执行命令并返回执行结果,其功能类似于os.popen(cmd).read()和commands.getoutput(cmd)。
subprocess.getstatusoutput(cmd)执行cmd命令,返回一个元组(命令执行状态, 命令执行结果输出),其功能类似于commands.getstatusoutput()。

 说明

  1. 在Python 3.5之后的版本中,官方文档中提倡通过subprocess.run()函数替代其他函数来使用subproccess模块的功能;
  2. 在Python 3.5之前的版本中,我们可以通过subprocess.call(),subprocess.getoutput()等上面列出的其他函数来使用subprocess模块的功能;
  3. subprocess.run()、subprocess.call()、subprocess.check_call()和subprocess.check_output()都是通过对subprocess.Popen的封装来实现的高级函数,因此如果我们需要更复杂功能时,可以通过subprocess.Popen来完成。
  4. subprocess.getoutput()和subprocess.getstatusoutput()函数是来自Python 2.x的commands模块的两个遗留函数。它们隐式的调用系统shell,并且不保证其他函数所具有的安全性和异常处理的一致性。另外,它们从Python 3.3.4开始才支持Windows平台。

参数解释

subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, timeout=None, check=False, universal_newlines=False)subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False, timeout=None)subprocess.getstatusoutput(cmd)subprocess.getoutput(cmd)
  • args: 要执行的shell命令,默认应该是一个字符串序列,如['df', '-Th']或('df', '-Th'),也可以是一个字符串,如'df -Th',但是此时需要把shell参数的值置为True。
  • shell: 如果shell为True,那么指定的命令将通过shell执行。如果我们需要访问某些shell的特性,如管道、文件名通配符、环境变量扩展功能,这将是非常有用的。当然,python本身也提供了许多类似shell的特性的实现,如glob、fnmatch、os.walk()、os.path.expandvars()、os.expanduser()和shutil等。
  • check: 如果check参数的值是True,且执行命令的进程以非0状态码退出,则会抛出一个CalledProcessError的异常,且该异常对象会包含 参数、退出状态码、以及stdout和stderr(如果它们有被捕获的话)。
  • stdin ,stdout, stderr(输入 输出 错误句柄): 该参数是传递给Popen.communicate(),通常该参数的值必须是一个字节序列,如果universal_newlines=True,则其值应该是一个字符串。
    • run()函数默认不会捕获命令执行结果的正常输出和错误输出,如果我们向获取这些内容需要传递subprocess.PIPE,然后可以通过返回的CompletedProcess类实例的stdout和stderr属性或捕获相应的内容;
    • call()和check_call()函数返回的是命令执行的状态码,而不是CompletedProcess类实例,所以对于它们而言,stdout和stderr不适合赋值为subprocess.PIPE;
    • check_output()函数默认就会返回命令执行结果,所以不用设置stdout的值,如果我们希望在结果中捕获错误信息,可以执行stderr=subprocess.STDOUT。
  • universal_newlines: 该参数影响的是输入与输出的数据格式,比如它的值默认为False,此时stdout和stderr的输出是字节序列;当该参数的值设置为True时,stdout和stderr的输出是字符串。

subprocess.CompletedProcess类

需要说明的是,subprocess.run()函数是Python3.5中新增的一个高级函数,其返回值是一个subprocess.CompletedPorcess类的实例,因此,subprocess.completedPorcess类也是Python 3.5中才存在的。它表示的是一个已结束进程的状态信息,它所包含的属性如下:

  • args: 用于加载该进程的参数,这可能是一个列表或一个字符串
  • returncode: 子进程的退出状态码。通常情况下,退出状态码为0则表示进程成功运行了;一个负值-N表示这个子进程被信号N终止了
  • stdout: 从子进程捕获的stdout。这通常是一个字节序列,如果run()函数被调用时指定universal_newlines=True,则该属性值是一个字符串。如果run()函数被调用时指定stderr=subprocess.STDOUT,那么stdout和stderr将会被整合到这一个属性中,且stderr将会为None
  • stderr: 从子进程捕获的stderr。它的值与stdout一样,是一个字节序列或一个字符串。如果stderr灭有被捕获的话,它的值就为None
  • check_returncode(): 如果returncode是一个非0值,则该方法会抛出一个CalledProcessError异常。

DEVNULL  STDOUT PIPE

介绍

在使用 Python 的 subprocess 模块执行外部命令时,可以通过不同的参数设置来控制标准输入、标准输出和标准错误之间的流动关系。

  • subprocess.DEVNULL:这是一个特殊的文件描述符,将其用作参数时,表示将相应的流重定向到操作系统的空设备(/dev/null)。例如,stdin=subprocess.DEVNULL 表示将标准输入重定向到空设备,即忽略输入;stdout=subprocess.DEVNULL 表示将标准输出丢弃,不进行任何输出;stderr=subprocess.DEVNULL 表示将标准错误丢弃,不进行任何错误输出。

  • subprocess.STDOUT:这个参数表示将标准错误合并到标准输出中。通过 stderr=subprocess.STDOUT,可以将标准错误的消息与标准输出一起处理,而不必单独处理标准错误。

  • subprocess.PIPE:这个参数表示将相应的流通过管道传递,并可以在程序中进行读取或写入。例如,stdout=subprocess.PIPE 表示将标准输出通过管道传递,并允许在 Python 程序中读取这个管道的内容。

案例

在第一个示例中,我们将标准输入、标准输出和标准错误都重定向到了空设备。这意味着在执行 echo 命令时,不会有任何输入、输出和错误消息输出。

在第二个示例中,我们将标准输入通过管道传递给 echo 命令,并捕获了标准输出和标准错误的内容。我们使用 PIPE 参数将它们传递给 Python 程序,并使用 decode() 方法将字节流转换为字符串,以便进行打印和处理。

在第三个示例中,我们将标准输入通过管道传递给 ls 命令。由于这个路径不存在,ls 命令会产生一个错误消息,并将其写入标准错误中。

但是,由于我们使用了 stderr=subprocess.STDOUT 参数,所以这个错误消息被合并到了标准输出中。在 Python 程序中可以捕获到整个输出流,并进行相应的处理和解析。

import subprocess# 将标准输入重定向到空设备,将标准输出和标准错误都重定向到空设备
subprocess.run("echo 'hello' > /dev/null 2>&1", shell=True, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)# 将标准输入重定向到空设备,将标准输出和标准错误均通过管道传递,并在 Python 程序中读取它们
result = subprocess.run("echo 'hello'", shell=True, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout = result.stdout.decode("utf-8")
stderr = result.stderr.decode("utf-8")
print(f"stdout: {stdout}")
print(f"stderr: {stderr}")# 将标准输入通过管道传递,将标准输出与标准错误合并为一个流,并在 Python 程序中读取它们
result = subprocess.run("ls /not/exist", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = result.stdout.decode("utf-8")
print(f"output: {output}")

stderr=subprocess.STDOUT

在使用 Python 的 subprocess 模块执行外部命令时,stderr=subprocess.STDOUT 是一种常见的参数设置。它表示将标准错误(stderr)与标准输出(stdout)合并为一个流,并通过标准输出返回。

通常,外部命令会将正常的输出信息写入标准输出(stdout),而将错误消息写入标准错误(stderr)。当使用 stderr=subprocess.STDOUT 时,标准错误的内容也会被重定向到标准输出中。

这个参数设置通常用于捕获命令执行的输出结果,包括标准输出和标准错误。通过将它们合并为一个流,可以方便地一起处理或记录。例如,你可以将输出保存到变量中,或将其写入日志文件进行后续分析。

案例

在上述例子中,subprocess.run() 函数执行了一个名为 some_command 的外部命令,并通过 stdout=subprocess.PIPE 参数捕获标准输出。

stderr=subprocess.STDOUT 参数将标准错误合并到标准输出中。最终,命令的输出结果被存储在 output 变量中,并打印出来。

这样就能够获取到命令执行的所有输出,包括正常的输出和错误信息,并进行相应的处理。

import subprocesscommand = "some_command"
result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
output = result.stdoutprint(output)

stdout=subprocess.DEVNULL (在 Windows 系统中需要使用 subprocess.PIPE 代替)

subprocess 模块是用来创建新进程,与之交互的标准输入、输出和错误流,并获取返回状态码的工具。

在使用 subprocess 模块时,可以使用 stdout=subprocess.DEVNULL 参数将子进程的标准输出重定向到 /dev/null,即丢弃输出。

具体来说,当 stdout=subprocess.DEVNULL 时,子进程的标准输出将被重定向到空设备文件 /dev/null,从而实现了丢弃输出的功能。这在不需要获取子进程标准输出结果,或者输出都被写入文件中时十分常见。

另外,类似的选项还有 stdin=subprocess.PIPEstderr=subprocess.PIPE,分别表示将子进程的标准输入和标准错误重定向到管道中,以便进行进一步的处理。

案例

上述代码中,subprocess.run(["ls", "-l"], stdout=subprocess.DEVNULL) 将调用 ls -l 命令,并将其标准输出重定向到 /dev/null,因此不会输出任何信息。

需要注意的是,subprocess.DEVNULL 只能在 Linux 或类 Unix 系统中使用,而在 Windows 系统中需要使用 subprocess.PIPE 代替。

import subprocess# 调用外部命令 ls,并将标准输出重定向到 /dev/null
subprocess.run(["ls", "-l"], stdout=subprocess.DEVNULL)

 stdout=subprocess.PIPE

subprocess.PIPEsubprocess 模块的一个常量,用于指定将子进程的标准输入、输出或错误连接到管道(pipe)中。

当你在调用 subprocess.run() 或其他与子进程交互的函数时,可以使用 subprocess.PIPE 参数来指定将子进程的输入、输出或错误重定向到管道中,以便进行进一步的处理。

案例

在上述例子中,subprocess.run() 函数执行了一个名为 some_command 的外部命令,并通过 stdout=subprocess.PIPE 参数捕获标准输出。

stderr=subprocess.STDOUT 参数将标准错误合并到标准输出中。最终,命令的输出结果被存储在 output 变量中,并打印出来。

这样就能够获取到命令执行的所有输出,包括正常的输出和错误信息,并进行相应的处理。

import subprocesscommand = "some_command"
result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
output = result.stdoutprint(output)

实例

subprocess.run()

>>> subprocess.run(["ls", "-l"])  # doesn't capture output
CompletedProcess(args=['ls', '-l'], returncode=0)>>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1>>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE)
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0,
stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n')

subprocess.call()

>>> subprocess.call(['ls',  '-l'])
总用量 160
drwxr-xr-x  2 wader wader   4096 12月  7  2015 公共的
drwxr-xr-x  2 wader wader   4096 12月  7  2015 模板
drwxr-xr-x  2 wader wader   4096 12月  7  2015 视频
drwxr-xr-x  2 wader wader   4096 12月  7  2015 图片
drwxr-xr-x  2 wader wader   4096 12月  7  2015 文档
drwxr-xr-x  2 wader wader   4096  4月 13  2016 下载
drwxr-xr-x  2 wader wader   4096 12月  7  2015 音乐
drwxr-xr-x  7 wader wader   4096  5月 26  2016 桌面
0
>>> subprocess.call('ls -l', shell=True)
总用量 160
drwxr-xr-x  2 wader wader   4096 12月  7  2015 公共的
drwxr-xr-x  2 wader wader   4096 12月  7  2015 模板
drwxr-xr-x  2 wader wader   4096 12月  7  2015 视频
drwxr-xr-x  2 wader wader   4096 12月  7  2015 图片
drwxr-xr-x  2 wader wader   4096 12月  7  2015 文档
drwxr-xr-x  2 wader wader   4096  4月 13  2016 下载
drwxr-xr-x  2 wader wader   4096 12月  7  2015 音乐
drwxr-xr-x  7 wader wader   4096  5月 26  2016 桌面
0
>>> subprocess.call(['ls',  '-l'], stdout=subprocess.DEVNULL)
0
>>> subprocess.call(['ls',  '-l', '/test'])
ls: 无法访问/test: 没有那个文件或目录
2

suprocess.check_call()

>>> subprocess.check_call(['ls',  '-l'])
总用量 160
drwxr-xr-x  2 wader wader   4096 12月  7  2015 公共的
drwxr-xr-x  2 wader wader   4096 12月  7  2015 模板
drwxr-xr-x  2 wader wader   4096 12月  7  2015 视频
drwxr-xr-x  2 wader wader   4096 12月  7  2015 图片
drwxr-xr-x  2 wader wader   4096 12月  7  2015 文档
drwxr-xr-x  2 wader wader   4096  4月 13  2016 下载
drwxr-xr-x  2 wader wader   4096 12月  7  2015 音乐
drwxr-xr-x  7 wader wader   4096  5月 26  2016 桌面
0
>>> subprocess.check_call('ls -l', shell=True)
总用量 160
drwxr-xr-x  2 wader wader   4096 12月  7  2015 公共的
drwxr-xr-x  2 wader wader   4096 12月  7  2015 模板
drwxr-xr-x  2 wader wader   4096 12月  7  2015 视频
drwxr-xr-x  2 wader wader   4096 12月  7  2015 图片
drwxr-xr-x  2 wader wader   4096 12月  7  2015 文档
drwxr-xr-x  2 wader wader   4096  4月 13  2016 下载
drwxr-xr-x  2 wader wader   4096 12月  7  2015 音乐
drwxr-xr-x  7 wader wader   4096  5月 26  2016 桌面
0
>>> subprocess.check_call('ls -l /test', shell=True)
ls: 无法访问/test: 没有那个文件或目录
Traceback (most recent call last):File "<stdin>", line 1, in <module>File "/usr/lib/python3.4/subprocess.py", line 557, in check_callraise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command 'ls -l /test' returned non-zero exit status 2

sbuprocess.check_output()

>>> ret = subprocess.check_output(['ls',  '-l'])
>>> print(ret)
b' \xe5\x85\xac\xe5\x85\xb1\xe7\x9a\x84\ndrwxr-xr-x  2 wader wader   4096 12\xe6\x9c\x88  7  2015 \xe6\xa8\xa1\xe6\x9d\xbf\ndrwxr-xr-x  2 wader wader   4096 12\xe6\x9c\x88  7  2015 \xe8\xa7\x86\xe9\xa2\x91\ndrwxr-xr-x  2 wader wader   4096 12\xe6\x9c\x88  7  2015 \xe5\x9b\xbe\xe7\x89\x87\ndrwxr-xr-x  2 wader wader   4096 12\xe6\x9c\x88  7  2015 \xe6\x96\x87\xe6\xa1\xa3\ndrwxr-xr-x  2 wader wader   4096  4\xe6\x9c\x88 13  2016 \xe4\xb8\x8b\xe8\xbd\xbd\ndrwxr-xr-x  2 wader wader   4096 12\xe6\x9c\x88  7  2015 \xe9\x9f\xb3\xe4\xb9\x90\ndrwxr-xr-x  7 wader wader   4096  5\xe6\x9c\x88 26  2016 \xe6\xa1\x8c\xe9\x9d\xa2\n'
>>> ret = subprocess.check_output(['ls',  '-l'], universal_newlines=True)
>>> print(ret)
总用量 160
drwxr-xr-x  2 wader wader   4096 12月  7  2015 公共的
drwxr-xr-x  2 wader wader   4096 12月  7  2015 模板
drwxr-xr-x  2 wader wader   4096 12月  7  2015 视频
drwxr-xr-x  2 wader wader   4096 12月  7  2015 图片
drwxr-xr-x  2 wader wader   4096 12月  7  2015 文档
drwxr-xr-x  2 wader wader   4096  4月 13  2016 下载
drwxr-xr-x  2 wader wader   4096 12月  7  2015 音乐
drwxr-xr-x  7 wader wader   4096  5月 26  2016 桌面

subprocess.getoutput()与subprocess.getstatusoutput()

>>> ret = subprocess.getoutput('ls -l')
>>> print(ret)
总用量 160
drwxr-xr-x  2 wader wader   4096 12月  7  2015 公共的
drwxr-xr-x  2 wader wader   4096 12月  7  2015 模板
drwxr-xr-x  2 wader wader   4096 12月  7  2015 视频
drwxr-xr-x  2 wader wader   4096 12月  7  2015 图片
drwxr-xr-x  2 wader wader   4096 12月  7  2015 文档
drwxr-xr-x  2 wader wader   4096  4月 13  2016 下载
drwxr-xr-x  2 wader wader   4096 12月  7  2015 音乐
drwxr-xr-x  7 wader wader   4096  5月 26  2016 桌面
>>> retcode, output = subprocess.getstatusoutput('ls -l')
>>> print(retcode)
0
>>> print(output)
总用量 160
drwxr-xr-x  2 wader wader   4096 12月  7  2015 公共的
drwxr-xr-x  2 wader wader   4096 12月  7  2015 模板
drwxr-xr-x  2 wader wader   4096 12月  7  2015 视频
drwxr-xr-x  2 wader wader   4096 12月  7  2015 图片
drwxr-xr-x  2 wader wader   4096 12月  7  2015 文档
drwxr-xr-x  2 wader wader   4096  4月 13  2016 下载
drwxr-xr-x  2 wader wader   4096 12月  7  2015 音乐
drwxr-xr-x  7 wader wader   4096  5月 26  2016 桌面
>>> retcode, output = subprocess.getstatusoutput('ls -l /test')
>>> print(retcode)
2
>>> print(output)
ls: 无法访问/test: 没有那个文件或目录

subprocess.Popen

介绍

该类用于在一个新的进程中执行一个子程序。前面我们提到过,上面介绍的这些函数都是基于subprocess.Popen类实现的,通过使用这些被封装后的高级函数可以很方面的完成一些常见的需求。

由于subprocess模块底层的进程创建和管理是由Popen类来处理的,因此,当我们无法通过上面哪些高级函数来实现一些不太常见的功能时就可以通过subprocess.Popen类提供的灵活的api来完成。

subprocess.Popen的构造函数 

class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=False,startup_info=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=())

参数说明:

  • args: 要执行的shell命令,可以是字符串,也可以是命令各个参数组成的序列。当该参数的值是一个字符串时,该命令的解释过程是与平台相关的,因此通常建议将args参数作为一个序列传递。
  • bufsize: 指定缓存策略,0表示不缓冲,1表示行缓冲,其他大于1的数字表示缓冲区大小,负数 表示使用系统默认缓冲策略。
  • stdin, stdout, stderr: 分别表示程序标准输入、输出、错误句柄。
  • preexec_fn: 用于指定一个将在子进程运行之前被调用的可执行对象,只在Unix平台下有效。
  • close_fds: 如果该参数的值为True,则除了0,1和2之外的所有文件描述符都将会在子进程执行之前被关闭。
  • shell: 该参数用于标识是否使用shell作为要执行的程序,如果shell值为True,则建议将args参数作为一个字符串传递而不要作为一个序列传递。
  • cwd: 如果该参数值不是None,则该函数将会在执行这个子进程之前改变当前工作目录。
  • env: 用于指定子进程的环境变量,如果env=None,那么子进程的环境变量将从父进程中继承。如果env!=None,它的值必须是一个映射对象。
  • universal_newlines: 如果该参数值为True,则该文件对象的stdin,stdout和stderr将会作为文本流被打开,否则他们将会被作为二进制流被打开。
  • startupinfo和creationflags: 这两个参数只在Windows下有效,它们将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如主窗口的外观,进程优先级等。

subprocess.Popen类的实例可调用的方法

方法描述
Popen.poll()用于检查子进程(命令)是否已经执行结束,没结束返回None,结束后返回状态码。
Popen.wait(timeout=None)等待子进程结束,并返回状态码;如果在timeout指定的秒数之后进程还没有结束,将会抛出一个TimeoutExpired异常。
Popen.communicate(input=None, timeout=None)该方法可用来与进程进行交互,比如发送数据到stdin,从stdout和stderr读取数据,直到到达文件末尾。
Popen.send_signal(signal)发送指定的信号给这个子进程。
Popen.terminate()停止该子进程。
Popen.kill()杀死该子进程。

关于communicate()方法的说明 

  • 该方法中的可选参数 input 应该是将被发送给子进程的数据,或者如没有数据发送给子进程,该参数应该是None。input参数的数据类型必须是字节串,如果universal_newlines参数值为True,则input参数的数据类型必须是字符串。
  • 该方法返回一个元组(stdout_data, stderr_data),这些数据将会是字节穿或字符串(如果universal_newlines的值为True)。
  • 如果在timeout指定的秒数后该进程还没有结束,将会抛出一个TimeoutExpired异常。捕获这个异常,然后重新尝试通信不会丢失任何输出的数据。但是超时之后子进程并没有被杀死,为了合理的清除相应的内容,一个好的应用应该手动杀死这个子进程来结束通信。
  • 需要注意的是,这里读取的数据是缓冲在内存中的,所以,如果数据大小非常大或者是无限的,就不应该使用这个方法。

subprocess.Popen使用实例 

实例1

>>> import subprocess
>>>
>>> p = subprocess.Popen('df -Th', stdout=subprocess.PIPE, shell=True)
>>> print(p.stdout.read())
Filesystem     Type      Size  Used Avail Use% Mounted on
/dev/vda1      ext4       40G   12G   26G  31% /
devtmpfs       devtmpfs  3.9G     0  3.9G   0% /dev
tmpfs          tmpfs     3.9G     0  3.9G   0% /dev/shm
tmpfs          tmpfs     3.9G  386M  3.5G  10% /run
tmpfs          tmpfs     3.9G     0  3.9G   0% /sys/fs/cgroup
tmpfs          tmpfs     783M     0  783M   0% /run/user/0
tmpfs          tmpfs     783M     0  783M   0% /run/user/1000

实例2

>>> obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> obj.stdin.write('print(1) \n')
>>> obj.stdin.write('print(2) \n')
>>> obj.stdin.write('print(3) \n')
>>> out,err = obj.communicate()
>>> print(out)
1
2
3>>> print(err)

实例3

>>> obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> out,err = obj.communicate(input='print(1) \n')
>>> print(out)
1>>> print(err)

实例4

实现类似df -Th | grep data命令的功能,实际上就是实现shell中管道的共功能。

>>> 
>>> p1 = subprocess.Popen(['df', '-Th'], stdout=subprocess.PIPE)
>>> p2 = subprocess.Popen(['grep', 'data'], stdin=p1.stdout, stdout=subprocess.PIPE)
>>> out,err = p2.communicate()
>>> print(out)
/dev/vdb1      ext4      493G  4.8G  463G   2% /data
/dev/vdd1      ext4     1008G  420G  537G  44% /data1
/dev/vde1      ext4      985G  503G  432G  54% /data2>>> print(err)
None

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/97337.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL_ERROR_INFO: “Duplicate entry ‘9003‘ for key ‘examination_info.exam_id‘“

今天刷题的时候&#xff0c;往数据库中插入一条语句&#xff0c;但是这个语句已经存在于数据库中了&#xff0c;所以不能用insert into 语句来插入&#xff0c;应该使用replace into 来插入。 REPLACE INTO examination_info(exam_id,tag,difficulty,duration,release_time) V…

springboot整合pi支付开发

pi支付流程图&#xff1a; 使用Pi SDK功能发起支付由 Pi SDK 自动调用的回调函数&#xff08;让您的应用服务器知道它需要发出批准 API 请求&#xff09;从您的应用程序服务器到 Pi 服务器的 API 请求以批准付款&#xff08;让 Pi 服务器知道您知道此付款&#xff09;Pi浏览器向…

【排序算法】堆排序详解与实现

一、堆排序的思想 堆排序(Heapsort)是指利用堆积树&#xff08;堆&#xff09;这种数据结构所设计的一种排序算法&#xff0c;它是选择排序的一种。它是通过堆&#xff08;若不清楚什么是堆&#xff0c;可以看我前面的文章&#xff0c;有详细阐述&#xff09;来进行选择数据&am…

论文阅读-- A simple transmit diversity technique for wireless communications

一种简单的无线通信发射分集技术 论文信息&#xff1a; Alamouti S M. A simple transmit diversity technique for wireless communications[J]. IEEE Journal on selected areas in communications, 1998, 16(8): 1451-1458. 创新性&#xff1a; 提出了一种新的发射分集方…

八大排序java

冒泡排序 /*** 冒泡排序&#xff1a;* 比较相邻的元素。如果第一个比第二个大&#xff0c;就交换他们两个。* 对每一对相邻元素作同样的工作&#xff0c;从开始第一对到结尾的最后一对。这步做完后&#xff0c;最后的元素会是最大的数。* 针对所有的元素重复以上的步骤&#x…

WEB各类常用测试工具

一、单元测试/测试运行器 1、Jest 知名的 Java 单元测试工具&#xff0c;由 Facebook 开源&#xff0c;开箱即用。它在最基础层面被设计用于快速、简单地编写地道的 Java 测试&#xff0c;能自动模拟 require() 返回的 CommonJS 模块&#xff0c;并提供了包括内置的测试环境 …

华为OD机试 - 最小步骤数(Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入&#xff1a;4 8 7 5 2 3 6 4 8 12、输出&#xff1a;23、说明&#xff1a;4、思路分析 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《…

aarch64 平台 musl gcc 工具链手动编译方法

目标 手动编译一个 aarch64 平台的 musl gcc 工具链 musl libc 与 glibc、uclibc 等,都是 标准C 库, musl libc 是基于系统调用之上的 标准C 库,也就是用户态的 标准C 库。 musl libc 轻量、开源、免费,是一些 操作系统的选择,当前 Lite-OS 与 RT-Smart 等均采用自制的 mu…

【Vue面试题八】、为什么data属性是一个函数而不是一个对象?

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;为什么data属性是一个函…

Spring实例化源码解析之Custom Events上集(八)

Events使用介绍 在ApplicationContext中&#xff0c;事件处理通过ApplicationEvent类和ApplicationListener接口提供。如果将实现ApplicationListener接口的bean部署到上下文中&#xff0c;每当一个ApplicationEvent被发布到ApplicationContext时&#xff0c;该bean将被通知。…

使用企业订货系统后的效果|软件定制开发|APP小程序搭建

使用企业订货系统后的效果|软件定制开发|APP小程序搭建 企业订货系统是一种高效的采购管理系统&#xff0c;它可以帮助企业更好地管理采购流程&#xff0c;降低采购成本&#xff0c;提高采购效率。 可以帮助企业提高销售效率和降低成本的软件工具。使用该系统后&#xff0c;企业…

如何使用 Tensor.art 实现文生图

摘要&#xff1a;Tensor.art 是一个基于 AI 的文本生成图像工具。本文介绍了如何使用 Tensor.art 来实现文生图的功能。 正文&#xff1a; 文生图是指将文本转换为图像的技术。它具有广泛的应用&#xff0c;例如在广告、教育和娱乐等领域。 Tensor.art 是一个基于 AI 的文本…

【SA8295P 源码分析】103 - QNX DDR RAM 内存布局分析

【SA8295P 源码分析】103 - QNX DDR RAM 内存布局分析 一、SA8295P QNX RAM 内存布局 (16G DDR)1.1 DDR 汇总描述1.2 QNX Meta reserved memory, DDR Rank01.3 Reserved for qnx1.4 Android GVM SysRam 相关内存(可修改)1.5 Reserved for qnx(不要修改)1.6 QNX SysRam 相关内…

强制删除文件?正确操作方法分享!

“我昨天在删除文件时有个文件一直删除不掉。想用强制删除的方法来把它删掉&#xff0c;应该怎么操作呢&#xff1f;谁能教教我呀&#xff1f;” 在使用电脑的过程中&#xff0c;我们有时候可能会发现文件无论怎么删除都无法删掉&#xff0c;如果我们想要强制删除文件但不知道怎…

Leetcode hot 100之回溯O(N!):选择/DFS

目录 框架&#xff1a;排列/组合/子集 元素无重不可复选 全排列 子集 组合&#xff1a;[1, n] 中的 k 个数 分割成回文串 元素无重不可复选&#xff1a;排序&#xff0c;多条值相同的只遍历第一条 子集/组合 先进行排序&#xff0c;让相同的元素靠在一起&#xff0c;如…

前端代码格式化规范总结

在日常开发过程中&#xff0c;经常会碰到代码格式化不一致的问题&#xff0c;还要就是 js 代码语法错误等没有及时发行改正&#xff0c;下面就介绍一下如何使用eslint、prettier、husky、lint-staged、commitizen来规范代码格式和提高代码质量的方法。 目录 准备工作代码检测代…

VMProtect使用教程(VC++MFC中使用)

VMProtect使用教程(VCMFC中使用) VMProtect是一种商业级别的代码保护工具&#xff0c;可以用于保护VC MFC程序。以下是使用VMProtect保护VC MFC程序的步骤&#xff1a; 1. 下载并安装VMProtect,C包含库及目录。 2. 在VC MFC项目中添加VMProtectSDK.h头文件&#xff0c;并在需…

Photoshop 笔记

目录 1. Photoshop 笔记1.1. 创建 A4 大小图片 1. Photoshop 笔记 1.1. 创建 A4 大小图片 Photoshop 的高版本自带了 A4、A5、A3、B5、B4、B3、C4、C5 等, 也可以直接制作打印美国信纸尺寸、法律文件用低、小报用纸等。 方法是: 新建 > 打印, 然后选择就可以了。 如果使…

Android ncnn-android-yolov8-seg源码解析 : 实现人像分割

1. 前言 上篇文章&#xff0c;我们已经将人像分割的ncnn-android-yolov8-seg项目运行起来了&#xff0c;后续文章我们会抽取出Demo中的核心代码&#xff0c;在自己的项目中&#xff0c;来接入人体识别和人像分割功能。 先来看下效果&#xff0c;整个图像的是相机的原图&#…

番外--Task2:

任务&#xff1a;root与普通用户的互切&#xff08;区别&#xff09;&#xff0c;启动的多用户文本见面与图形界面的互切命令&#xff08;区别&#xff09;。 输入图示命令&#xff0c;重启后就由图形界面转成文本登录界面&#xff1b; 输入图示命令&#xff0c;重启后就由文本…