1、subprocess调用系统的命令

#!/usr/bin/env python
# -*- coding: utf-8 -*- import subprocess
import sys completed = subprocess.run(['ls',sys.argv[1],'-l'])
print('运行结果',completed.returncode)

subprocess_os_system.py

运行效果

[root@ mnt]# python3 subprocess_os_system.py /mnt/
total
-rw-r--r-- root root Dec : subprocess_os_system.py

2、subprocess利用shell进程运行命令

#!/usr/bin/env python
# -*- coding: utf-8 -*- import subprocess completed=subprocess.run('echo $HOME',shell=True) print('执行返回码:',completed.returncode)

subprocess_shell_variables.py

运行效果

[root@ mnt]# python3 subprocess_shell_variables.py
/root
执行返回码:  

3、subprocess错误的处理

(1)、check=True,会检查退出码,如果返回非0,则抛出subprocess.CalledProcessError异常

(2)、check=False,不会检查退出码

#!/usr/bin/env python
# -*- coding: utf-8 -*- import subprocess try:
subprocess.run(['false'], check=True) except subprocess.CalledProcessError as err:
print('运行错误:', err)

subprocess_run_check.py

运行效果

[root@ mnt]# python3 subprocess_run_check.py
运行错误: Command '['false']' returned non-zero exit status .

4、subprocess管道显示运行结果

#!/usr/bin/env python
# -*- coding: utf-8 -*- import subprocess
import sys completed = subprocess.run(['ls', sys.argv[1], '-l'], stdout=subprocess.PIPE)
print('completed.returncode: ',completed.returncode)
print('completed.stdout: \n',str(completed.stdout,'utf-8'))

subprocess_run_output.py

运行效果

[root@ mnt]# python3 subprocess_run_output.py /mnt/
completed.returncode:
completed.stdout:
total
-rw-r--r-- root root Dec : subprocess_run_output.py

5、 subprocess管道显示以及异常的捕捉

#!/usr/bin/env python
# -*- coding: utf-8 -*- import subprocess try:
completed = subprocess.run('echo to stdout;'
'echo to stderr 1>&2;'
'exit 1',
check=True,
shell=True,
stdout=subprocess.PIPE)
except subprocess.CalledProcessError as err:
print('执行错误: ', err)
else:
print('completed.returncode: ', completed.returncode)
print('completed.stdout: ', str(completed.stdout, encoding='utf-8'))

subprocess_run_output_error.py

运行效果

[root@ mnt]# python3 subprocess_run_output_error.py
to stderr
执行错误: Command 'echo to stdout;echo to stderr 1>&2;exit 1' returned non-zero exit status .

 6、subprocess管道显示和管道错误信息的显示

#!/usr/bin/env python
# -*- coding: utf-8 -*- import subprocess try:
completed = subprocess.run('echo to stdout;'
'echo to stderr 1>&2;'
'exit 1',
check=False,#如果check=False,则不抛出 subprocess.CalledProcessError 异常
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
except subprocess.CalledProcessError as err:
print('执行错误: ', err)
else:
print('completed.returncode: ', completed.returncode)
print('completed.stdout: ', completed.stdout.decode('utf-8'))
print('completed.stderr: ', completed.stderr.decode('utf-8'))

subprocess_run_output_error_trap.py

运行效果

[root@ mnt]# python3 subprocess_run_output_error_trap.py
completed.returncode:
completed.stdout: to stdout completed.stderr: to stderr

7、subprocess之check_output函数,实现错误信息与命令执行结果一起输出显示

import subprocess

try:
completed = subprocess.check_output('echo to stdout; echo to stderr 1>&2;',
shell=True,
stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as err:
print('执行错误: ', err)
else:
print('completed.returncode: ', completed.returncode)
print('completed.stdout: ', str(completed.stdout, encoding='utf-8'))

subprocess_run_output_error_trap.py

运行效果

[root@ mnt]# python3 subprocess_run_output_error_trap.py
completed: b'to stdout\nto stderr\n'
completed.stdout: to stdout
to stderr

8、subprocess抑制输出,相当于把标准输出或标准错误写入/dev/null

#!/usr/bin/env python
# -*- coding: utf-8 -*- import subprocess try:
completed = subprocess.run('echo to stdout; echo to stderr 1>&2;',
shell=True,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
except subprocess.CalledProcessError as err:
print('执行错误: ', err)
else:
print('completed.returncode: ', completed.returncode)
print('completed.stdout: ', completed.stdout)
print('completed.stderr: ', completed.stderr)

subprocess_run_output_error_suppress.py

运行效果

[root@ mnt]# python3 subprocess_run_output_error_suppress.py
completed.returncode:
completed.stdout: None
completed.stderr: None

8、subprocess直接使用管道处理读取

由于call()、run()、check_output()都是Popen类的装饰器,直接使用Popen更容易的控制命令执行结果的标准的输入输出

#!/usr/bin/env python
# -*- coding: utf-8 -*- import subprocess proc = subprocess.Popen(['echo', 'Popen 输出'],
stdout=subprocess.PIPE, )
stdout_value = proc.communicate()[0].decode('utf-8')
print('stdout:', repr(stdout_value)) #返回一个对象的 string 格式。

subprocess_popen_read.py

运行效果

[root@ mnt]# python3 subprocess_popen_read.py
stdout: 'Popen 输出\n'

9、subprocess直接使用管道处理写数据

#!/usr/bin/env python
# -*- coding: utf-8 -*- import subprocess print('write:')
proc = subprocess.Popen(
['cat', '-'],
stdin=subprocess.PIPE,
)
proc.communicate('我写入数据\n'.encode('utf-8'))

subprocess_popen_write.py

运行效果

[root@ mnt]# python3 subprocess_popen_write.py
write:
我写入数据

10、 Popen进程双向通道,实现同时完成标准的读写

#!/usr/bin/env python
# -*- coding: utf-8 -*- import subprocess proc = subprocess.Popen(
['cat', '-'],
stdout=subprocess.PIPE,
stdin=subprocess.PIPE
) msg = '我是标准输入的内容 stdin'.encode('utf-8')
stdout_value = proc.communicate(msg)[0].decode('utf-8')
print('stdout_value: ', stdout_value)

subprocess_popen2.py

运行效果

[root@ mnt]# python3 subprocess_popen2.py
stdout_value: 我是标准输入的内容 stdin

 11、Popen捕获错误输出,实现标准错误信息的显示

#!/usr/bin/env python
# -*- coding: utf-8 -*- import subprocess proc = subprocess.Popen(
'cat -;echo "to stderr" 1>&2',
shell=True,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=subprocess.PIPE
) msg = '我是标准输入的内容 stdin'.encode('utf-8')
stdout_value, stderr_value = proc.communicate(msg)
print('stdout_value: ', repr(stdout_value.decode('utf-8')))
print('stderr_value: ', repr(stderr_value.decode('utf-8')))

subprocess_popen3.py

运行效果

[root@ mnt]# python3 subprocess_popen3.py
stdout_value: '我是标准输入的内容 stdin'
stderr_value: 'to stderr\n'

 12、Popen把标准错误切换标准输出显示

#!/usr/bin/env python
# -*- coding: utf-8 -*- import subprocess proc = subprocess.Popen(
'cat -;echo "to stderr" 1>&2',
shell=True,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=subprocess.STDOUT
) msg = '我是标准输入的内容 stdin'.encode('utf-8')
stdout_value, stderr_value = proc.communicate(msg)
print('stdout_value: ', repr(stdout_value.decode('utf-8')))
print('stderr_value: ', repr(stderr_value))

subprocess_popen4.py

运行效果

[root@ mnt]# python3 subprocess_popen4.py
stdout_value: '我是标准输入的内容 stdinto stderr\n'
stderr_value: None

13、Popen管道之间的连接,相当于Linux命令管道传送

如 linux命令

[root@ mnt]# cat cz.txt | grep  | head -n 

用python实现如上命令的方法

#!/usr/bin/env python
# -*- coding: utf-8 -*- import subprocess cat = subprocess.Popen(
['cat', '/mnt/cz.txt'],
stdout=subprocess.PIPE,
) grep = subprocess.Popen(
['grep', ''],
stdin=cat.stdout,
stdout=subprocess.PIPE,
) head = subprocess.Popen(
['head', '-n', ''],
stdin=grep.stdout,
stdout=subprocess.PIPE,
) result_stdout = head.communicate()[0].decode('utf-8') print(result_stdout)

subprocess_pipes.py

运行效果

[root@ mnt]# python3 subprocess_pipes.py 

14、Popen命令之间的交互

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#中继程序 import sys sys.stderr.write('repeater.py: starting\n')
sys.stderr.flush() while True:
next_line = sys.stdin.readline()
sys.stderr.flush()
if not next_line:
break
sys.stdout.write(next_line)
sys.stdout.flush() sys.stderr.write('repeater.py: exiting\n')
sys.stderr.flush()

repeater.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#交互的程序 import io
import subprocess print('#####一次一行输出#####') # 创建一个Popen对象,执行的命令结果通过管道传输
proc = subprocess.Popen(
'python3 /mnt/repeater.py',
shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
) # 创建输入的缓冲区,设置每发一次数据,单独一行
stdin = io.TextIOWrapper(
proc.stdin,
encoding='utf-8',
line_buffering=True, # send data on newline
) # 创建输出的缓冲区
stdout = io.TextIOWrapper(
proc.stdout,
encoding='utf-8',
) for i in range(5):
line = '{}\n'.format(i)
stdin.write(line) # 写入缓冲区
output = stdout.readline() # 从输出缓冲区读取一行
print(output.rstrip()) # 去除右边的空格
remainder = proc.communicate()[0].decode('utf-8') # 读取管理的结果
print(remainder) print('#####一次全部输出#####')
proc = subprocess.Popen(
'python3 /mnt/repeater.py',
shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
)
stdin = io.TextIOWrapper(
proc.stdin,
encoding='utf-8',
)
for i in range(5):
line = '{}\n'.format(i)
stdin.write(line)
stdin.flush() output = proc.communicate()[0].decode('utf-8')
print(output)

interaction.py

运行效果

[root@ mnt]# python3 repeater.py  #开启中继程序监听数据收和发
repeater.py: starting [root@ mnt]# python3 interaction.py
#####一次一行输出#####
repeater.py: starting repeater.py: exiting #####一次全部输出#####
repeater.py: starting
repeater.py: exiting

 15、利于模块signal实现进程间信号的传递,即是利父程去管理子进程,使用os.kill关闭子进程未运行完成的程序

#!/usr/bin/env python
# -*- coding: utf-8 -*- import os
import signal
import time
import sys pid = os.getpid()
received = False def signal_usr1(signum, frame):
"Callback invoked when a signal is received"
global received
received = True
print('CHILD {:>6}: Received USR1'.format(pid))
sys.stdout.flush() print('CHILD {:>6}: 设置信号处理程序'.format(pid))
sys.stdout.flush()
signal.signal(signal.SIGUSR1, signal_usr1) print('CHILD {:>6}: 暂停等待信号'.format(pid))
sys.stdout.flush()
time.sleep(5) if not received:
print('CHILD {:>6}: 从未接收到信号'.format(pid))

signal_child.py

#!/usr/bin/env python
# -*- coding: utf-8 -*- import os
import signal
import subprocess
import time
import sys proc = subprocess.Popen(['python3', 'signal_child.py']) print('PARENT : Pausing before sending signal...') sys.stdout.flush() time.sleep(1) print('PARENT : Signaling child') sys.stdout.flush() os.kill(proc.pid, signal.SIGUSR1)

signal_parent.py

运行结果

[root@ mnt]# python3 signal_parent.py
PARENT : Pausing before sending signal...
CHILD : 设置信号处理程序
CHILD : 暂停等待信号
PARENT : Signaling child
CHILD : Received USR1

 16、进程组和会话

问题:如果使用Popen创建了子进程,那么创建的子进程就不会接收到父进程的信号,问题代码如下:

import os
import signal
import subprocess
import tempfile
import time
import sys script = '''#!/bin/sh
echo "Shell script in process $$"
set -x
python3 /mnt/signal_child.py
'''
#在/tmp目录下,将script写入一个临时文件
script_file = tempfile.NamedTemporaryFile('wt')
script_file.write(script)
script_file.flush() proc = subprocess.Popen(['sh', script_file.name]) #script_file.name ==> /tmp/tmprizk8l2p print('PARENT : Pausing before signaling {}...'.format(proc.pid))
sys.stdout.flush() time.sleep(1) print('PARENT : Signaling child {}'.format(proc.pid))
sys.stdout.flush() os.kill(proc.pid, signal.SIGUSR1)
time.sleep(3)

subprocess_signal_parent_shell.py

#!/usr/bin/env python
# -*- coding: utf-8 -*- import os
import signal
import time
import sys pid = os.getpid()
received = False def signal_usr1(signum, frame):
"Callback invoked when a signal is received"
global received
received = True
print('CHILD {:>6}: Received USR1'.format(pid))
sys.stdout.flush() print('CHILD {:>6}: 设置信号处理程序'.format(pid))
sys.stdout.flush()
signal.signal(signal.SIGUSR1, signal_usr1) print('CHILD {:>6}: 暂停等待信号'.format(pid))
sys.stdout.flush()
time.sleep(3) if not received:
print('CHILD {:>6}: 从未接收到信号'.format(pid))

signal_child.py

运行效果

[root@ mnt]# python3 subprocess_signal_parent_shell.py
Shell script in process
+ python3 /mnt/signal_child.py
PARENT : Pausing before signaling ...
CHILD : 设置信号处理程序
CHILD : 暂停等待信号
PARENT : Signaling child
CHILD : 从未接收到信号
#以上由Popen创建了子进程shell,shell解释器又创建进程调用signal_child.py程序,所以产生进程id不一样,导致进程之间无法相互发信号通讯。

利用进程组之间的通信,解决进程之间pid识别不到,导致信号传输失败的问题

#!/usr/bin/env python
# -*- coding: utf-8 -*- import os
import signal
import subprocess
import tempfile
import time
import sys def show_setting_prgrp():
print('Calling os.setpgrp() from {}'.format(os.getpid()))
os.setpgrp()
print('Process group is now {}'.format(os.getpgrp()))
sys.stdout.flush() script = '''#!/bin/sh
echo "Shell script in process $$"
set -x
python3 /mnt/signal_child.py
'''
script_file = tempfile.NamedTemporaryFile('wt')
script_file.write(script)
script_file.flush() proc = subprocess.Popen(
['sh', script_file.name],
preexec_fn=show_setting_prgrp,
) print('PARENT : Pausing before signaling {}...'.format(proc.pid))
sys.stdout.flush()
time.sleep(1) print('PARENT : Signaling process group {}'.format(proc.pid))
sys.stdout.flush() os.killpg(proc.pid, signal.SIGUSR1)
time.sleep(3)

subprocess_signal_setpgrp.py

运行效果

[root@ mnt]# python3 subprocess_signal_setpgrp.py
Calling os.setpgrp() from
Process group is now
Shell script in process
+ python3 /mnt/signal_child.py
PARENT : Pausing before signaling ...
CHILD : 设置信号处理程序
CHILD : 暂停等待信号
PARENT : Signaling process group
CHILD : Received USR1

Python之subprocess模块的使用的更多相关文章

  1. Python中subprocess 模块 创建并运行一个进程

     python的subprocess模块,看到官方声明里说要尽力避免使用shell=True这个参数,于是测试了一下: from subprocess import call import shlex ...

  2. python的subprocess模块(写的不错留作查询)

    python的subprocess模块 subprocess模块是python从2.4版本开始引入的模块.主要用来取代 一些旧的模块方法,如os.system.os.spawn*.os.popen*. ...

  3. python 利用python的subprocess模块执行外部命令,获取返回值

    有时执行dos命令需要保存返回值 需要导入库subprocess import subprocess p = subprocess.Popen('ping www.baidu.com', shell= ...

  4. python之subprocess模块详解--小白博客

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

  5. python中subprocess模块

    subprocess  模块 subprocess称之为子进程,进程是一个正在进行的程序 子进程是由另一个正在运行的程序启动的程序,例如QQ聊天点击一个链接,打开了浏览器,那么浏览器称之为QQ的子进程 ...

  6. python的subprocess模块执行shell命令

    subprocess模块可以允许我们执行shell命令 一般来说,使用run()方法就可以满足大部分情况 使用run执行shell命令 In [5]: subprocess.run('echo &qu ...

  7. Python之Subprocess模块

    PS:打开文件时候加b参数是代表以二进制方式打开,在Linux加不加都可以,在windows上面最好加b参数否则可能会出现问题 使用system返回执行结果不赋值,使用popen返回了结果赋值给cmd ...

  8. Python之subprocess模块、sys模块

    一.subprocess模块 # import os # os.system('tasklist') #类似cmd输入系统命令 ''' subprocess的目的就是启动一个新的进程并且与之通信. s ...

  9. python基础--subprocess模块

    可以执行shell命令的相关模块和函数有: os.system os.spawn* os.popen*          --废弃 popen2.*           --废弃 commands.* ...

  10. Python的subprocess模块(二)

    原文:http://blog.chinaunix.net/uid-26000296-id-4461522.html 一.subprocess 模块简介 subprocess最早是在2.4版本中引入的. ...

随机推荐

  1. 20190507-学习dubbo有感于梁飞

    “作为一名程序员,BAT肯定是大多数人都想进的,仿佛是一种情愫,就像学生时代的我们对清华北大的向往感觉一样.Dubbo团队中,其中主要负责人就是梁飞了,梁飞的经历还是蛮励志的.梁飞,花名虚极, 200 ...

  2. 在ASP.NET Core 2.0中使用Facebook进行身份验证

    已经很久没有更新自己的技术博客了,自从上个月末来到天津之后把家安顿好,这个月月初开始找工作,由于以前是做.NET开发的,所以找的还是.NET工作,但是天津这边大多还是针对to B(企业)进行定制开发的 ...

  3. POJ - 3249 Test for Job (在DAG图利用拓扑排序中求最长路)

    (点击此处查看原题) 题意 给出一个有n个结点,m条边的DAG图,每个点都有权值,每条路径(注意不是边)的权值为其经过的结点的权值之和,每条路径总是从入度为0的点开始,直至出度为0的点,问所有路径中权 ...

  4. Java实现AES对称加密算法

    Java代码实现 import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.KeyGener ...

  5. Web前端开发JQuery框架

    JQuery 是一个兼容多浏览器支持的JavaScript库,其核心理念是write less,do more(写得更少,做得更多),它是轻量级的js库,兼容CSS3还兼容各种浏览器,需要注意的是后续 ...

  6. 怎样在 Vue 中使用 v-model 实现双向数据绑定?

    1. 所谓 双向数据绑定, 可以理解为: 修改 A , B 会跟着被修改, 修改 B , A 会跟着被修改. 常用在需要 进行用户输入的地方, 比如 这些 html 标签:  input.select ...

  7. JavaScript笔记(1)

    1.JavaScript的基本概念 JavaScript是一个解释型的脚本语言 JavaScript可以写在HTML文档内部的任何地方 行内式 内嵌式 链入式:<script src=" ...

  8. pycharm问题合集

    一  打开pycharm出现 点击右上角的配置之后 配置正确的python路径 又出现 解决办法 删除所有的解释器,据说是重名导致的. 然后在配置一次 二  ModuleNotFoundError: ...

  9. Oracle笔记(四) 简单查询、限定查询、数据的排序

    一.简单查询 SQL(Structured Query Language) 结构化查询语言,是一种数据库查询和程序设计语言,用于存取数据以及查询.更新和管理关系数据库系统.ANSI(美国国家标准学会) ...

  10. python常用模块:包的使用、init作用、相对导入绝对导入与内置函数

    今天主要讲的内容有: 一.包的详解二.相对导入和绝对导入三.内置模块补充 一.包的详解 1.包是什么 包其实也是一个模块,只不过是一个大的模块下包含一堆模块的载体 本质上也是一个文件夹,与普通文件的区 ...