1497.Linux下的cx_oracle离线安装
离线安装cx_Oracle步骤:
1、系统环境:
Linux环境:Redhat6.5,Python2.7
2、下载软件:
oracle客户端官网下载地址:http://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html
oracle-instantclient12.2-basic-12.2.0.1.0-1.x86_64.rpm
oracle-instantclient12.2-devel-12.2.0.1.0-1.x86_64.rpm
oracle-instantclient12.2-sqlplus-12.2.0.1.0-1.x86_64.rpm
Python模块cx_Oracle官网下载地址:
https://pypi.python.org/pypi/cx_Oracle
cx_Oracle-6.0rc1.tar.gz
3、软件安装:
3.1 oracle客户端安装:
rpm –ivh oracle-instantclient12.2-basic-12.2.0.1.0-1.x86_64.rpm
rpm –ivh oracle-instantclient12.2-devel-12.2.0.1.0-1.x86_64.rpm
rpm –ivh oracle-instantclient12.2-sqlplus-12.2.0.1.0-1.x86_64.rpm
3.2 oracle模块安装:(源码安装方法)
tar -zxvf cx_Oracle-6.0rc1.tar.gz
cd cx_Oracle-6.0rc1.tar.gz
python27 setup.py build
python27 setup.py install
4、测试:
进入Python
Python 2.7.13 (default, Apr 6 2017, 12:32:43)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
Type “help”, “copyright”, “credits” or “license” for more information.
import cx_Oracle
quit();
完成。
Python安装cx_oracle操作
1.cx_Oracle概述
cx_Oracle是一个Python 扩展模块,通过使用所有数据库访问模块通用的数据库 API来实现 Oracle 数据库的查询和更新。为使用一些专为 Oracle 设计的特性,还加入了多个通用数据库 API 的扩展。cx_Oracle 的开发历时多年,涵盖了大多数需要在 Python 中访问 Oracle 的客户的需求。
安装cx_Oracle使用pip命令: pip install cx_Oracle
2.连接oracle数据库
cx_Oracle.connect(‘scott’, ‘scott’, ‘127.0.0.1:1521/orcl’)
cx_Oracle.connect(‘scott/scott@127.0.0.1:1521/orcl’)
3.ORACLE的查询
#简单查询
import cx_Oracle
db_conn = cx_Oracle.connect(‘scott’, ‘scott’, ‘127.0.0.1:1521/orcl’)
db_cursor=db_conn.cursor()
sql_cmd=‘SELECT * FROM students’
db_cursor.execute(sql_cmd)
for row in db_cursor:
print(row)
db_cursor.close()
db_conn.close()
#带参数查询
db_conn = cx_Oracle.connect(‘scott’, ‘scott’, ‘127.0.0.1:1521/orcl’)
db_cursor=db_conn.cursor()
sql_cmd=‘SELECT * FROM students where ID = :id’
sql_p_id={‘id’:2}
db_cursor.execute(sql_cmd,sql_p_id)
for row in db_cursor:
print(row)
db_cursor.close()
db_conn.close()
#获取单行可以使用fetchone函数;获取多行记录,可以使用fetchall函数
import cx_Oracle
db_conn = cx_Oracle.connect(‘scott’, ‘scott’, ‘127.0.0.1:1521/orcl’)
db_cursor=db_conn.cursor()
sql_cmd=‘SELECT * FROM students’
db_cursor.execute(sql_cmd)
print(db_cursor.fetchone())
db_cursor.close()
db_conn.close()
4.ORACLE的DML
import cx_Oracle
from datetime import datetime
db_conn = cx_Oracle.connect(‘scott’, ‘scott’, ‘127.0.0.1:1521/orcl’)
db_cursor=db_conn.cursor()
sql_cmd = ‘INSERT INTO students(id, name, age,birth) VALUES(:id, :name, :age,:birth)’
db_cursor.execute(sql_cmd,(11,‘王五2’,12,datetime(2017,9,1,12,40,12)))
db_cursor.execute(sql_cmd,(22,‘赵六’,12,datetime(2017,9,1,12,40,12)))
db_conn.commit()
db_cursor.close()
db_conn.close()
import cx_Oracle
from datetime import datetime
db_conn = cx_Oracle.connect(‘scott’, ‘scott’, ‘127.0.0.1:1521/orcl’)
db_cursor=db_conn.cursor()
sql_cmd = ‘INSERT INTO students(id, name, age,birth) VALUES(:id, :name, :age,:birth)’
db_cursor.executemany(sql_cmd, [(15, ‘王五2’, 12, datetime(2017, 9, 1, 12, 40, 12)),(16, ‘赵六’, 12, datetime(2017, 9, 1, 12, 40, 12))])
db_conn.commit()
db_cursor.close()
db_conn.close()
5.调用存储过程和函数
–存储过程代码:
CREATE OR REPLACE PROCEDURE P_DEMO(V1 IN VARCHAR2, V2 OUT VARCHAR2) IS
BEGIN
V2 := V1;
END;
#Python代码:
import cx_Oracle
db_conn = cx_Oracle.connect(‘scott’, ‘scott’, ‘127.0.0.1:1521/orcl’)
db_cursor=db_conn.cursor()
str=‘abdd’
msg =db_cursor.var(cx_Oracle.STRING)
db_cursor.callproc(‘p_demo’,[str,msg])
db_conn.commit()
print(msg)
print(msg.getvalue())
db_cursor.close()
db_conn.close()
–函数代码:
CREATE OR REPLACE function F_DEMO(V1 VARCHAR2,V2 VARCHAR2) RETURN VARCHAR2
IS
BEGIN
RETURN V1 || v2;
END;
#Python代码:
import cx_Oracle
db_conn = cx_Oracle.connect(‘scott’, ‘scott’, ‘127.0.0.1:1521/orcl’)
db_cursor=db_conn.cursor()
str=db_cursor.callfunc(‘f_demo’,cx_Oracle.STRING,[‘abc’,‘ddd’])
print(str)
db_conn.commit()
db_cursor.close()
db_conn.close()
原文链接:https://blog.csdn.net/qq_73428784/article/details/128191578
Linux中安装cx_Oracle
背景介绍
在linux服务器上,python版本为3.7安装cx_Oracle。
安装 instantclient
有账号的可以在官网上下载,官网网址如下:
https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html
没有账号又不想注册的,可以在gitee上下载,有github账号或者华为账号就行。
https://gitee.com/appcity/oracle-instantclient/blob/master/instantclient-basic-linux.x64-12.2.0.1.0.zip
新建oracle文件
这里是在data路径下,可以选择自己的路径
mkdir -p /data/oracle
cd /data/oracle
解压文件
将下载好的instantclient-basic-linux.x64-12.2.0.1.0.zip放在之前建好的路径下,然后使用如下命令解压:
unzip instantclient-basic-linux.x64-12.2.0.1.0.zip
建立连接,依次执行下面命令:
cd /opt/oracle/instantclient_12_2
ln -s libclntsh.so.12.1 libclntsh.so
ln -s libocci.so.12.1 libocci.so
sudo sh -c “echo /opt/oracle/instantclient_12_2 > /etc/ld.so.conf.d/oracle-instantclient.conf”
sudo ldconfig
安装cx_Oracle
pip3 install cx_Oracle==8.3.0
测试
import cx_Oracle
conn = cx_Oracle.connect(‘账号’, ‘密码’, ‘XXip’) #连接数据库
cursor = conn.cursor()
print(“数据库连接成功!!”)
1501.python执行Linux命令
- os.system(cmd)
返回值是shell指令运行后返回的状态码,int类型,0表示shell指令成功执行,256/512表示未找到,该方法适用于shell命令不需要输出内容的场景。
os.system(cmd)会启动子进程,在子进程中执行cmd,如果cmd有执行内容,会在标准输出显示。
import os
val = os.system(‘pwd’)
/home/stephenprint val
0val = os.system(‘ls record.txt’)
ls: cannot access record.txt: No such file or directoryprint val
512
- os.popen()
该方法以文件的形式返回shell指令运行后的结果,需要获取内容时可使用read()或readlines()方法。
os.system(cmd)或os.popen(cmd),前者返回值是脚本的退出状态码,后者的返回值是脚本执行过程中的输出内容。实际使用时视需求情况而选择。
os.popen(‘pwd’)
<open file ‘pwd’, mode ‘r’ at 0xb7751e90>os.popen(‘pwd’).read()
‘/home/stephen\n’
- commands模块
(1)commands.getstatusoutput(cmd),其以元组(status,output)的形式返回命令执行后的返回状态和执行结果。其中,对cmd的执行实际上是按照{cmd;} 2>&1的方式,所以output中包含控制台输出信息或者错误信息,output中不包含尾部的换行符。
import commands
status, result = commands.getstatusoutput(‘pwd’)
print status
0print result
/home/stephen
(2)commands.getoutput(cmd),返回cmd的输出结果。result = commands.getoutput(‘pwd’)
print result
/home/stephen
(3)commands.getstatus(file),返回ls -l file的执行结果字符串,调用了getoutput,不建议使用此方法status = commands.getstatus(‘package’)
print status
drwxr-xr-x. 5 root root 4096 Nov 27 10:42 package
- subprocess模块
python3 中变化:
1)使用os.system(cmd) 无法获取输出内容
2)使用os.popen(cmd).read()可以获取到返回的json体{aa},通过json.loads({aa})可以将json体转为字典样式
3)commands模块在Python3.0中被废弃了
4)subprocess.getstatusoutput(cmd)输出结果类似于python2中的commands.getstatusoutput(cmd),返回一个元组,元组的第2个值是执行结果{aa},通过json.loads({aa})可以将json体转为字典样式。
subprocess模块
python 调用 方法 实现 shell命令的执行,其是 开启了一个子进程。
从Python 2.4开始,Python引入subprocess模块来管理子进程,以取代一些旧模块的方法:如 os.system、os.spawn、os.popen
不但可以调用外部的命令作为子进程,而且可以 连接到子进程 的input/output/error管道,获取相关的返回信息。
所以 os.system或者os.popen等模块,要不还是放弃吧。
其中最有用的是 call(执行系统命令)、check_call(执行结果不为0则抛出异常)、
check_output(最方便的获取执行的输出的函数)、Popen+PIPE(支持管道的多命令执行)。
例子:
call
会开启一个 子进程 去执行,并且等待子进程结束才继续执行其他的,使用起来非常方便
import subprocess
res = subprocess.call([“ls”, “-al”])
print("\n")
args参数(call的第一个参数) 由字符串形式提供且有 多个命令参数时,需要提供 shell=True 参数:
res = subprocess.call(“ls -al”, shell=True)
与call方法类似,不同在于如果命令行 执行成功,check_call返回返回码0,执行失败 就会 抛出 subprocess.CalledProcessError 异常。
subprocess.CalledProcessError 异常包括returncode、cmd、output等属性,其中returncode是子进程的退出码,cmd是子进程的执行命令,output为None。
import subprocess
try:
res = subprocess.check_call([‘ls’, ‘?’])
print (‘ls:’, res)
except subprocess.CalledProcessError as e:
print(‘returncode:’, e.returncode)
print(‘cmd:’, e.cmd)
print(‘output:’, e.output)
输出:
‘’’
ls: 无法访问’?’: 没有那个文件或目录
returncode: 2
cmd: [‘ls’, ‘?’]
output: None
‘’’
Popen
与call方法类似,不同在于 Popen 是无阻塞的,会和主程序并行运行,而 call 必须 等待命令执行完毕 再执行 后面的 代码。
import subprocess
res = subprocess.Popen(“ls -al”, shell=True)
print(res)
print(123)
说明:
‘’’
先执行 两个 print ,然后再 执行 命令, 所以输出是:
123
总用量 60
drwxr-xr-x 8 hero hero 4096 7月 6 17:37 .
drwxr-xr-x 6 hero hero 4096 4月 12 13:48 …
drwxr-xr-x 5 hero hero 4096 7月 6 17:35 aaa
-rw-r–r-- 1 hero hero 1008 7月 6 16:47 aaa.py
‘’’
Python模块之subprocess
一 简介
在使用Python 开发MySQL自动化相关的运维工具的时候,遇到一些有意思的问题,本文介绍Python的 subprocess 模块以及如何和MySQL交互具体操作,如启动 ,关闭 ,备份数据库。
二 基础知识
Python2.4引入subprocess模块来管理子进程,可以像Linux 系统中执行shell命令那样fork一个子进程执行外部的命令,并且可以连接子进程的output/input/error管道,获取命令执行的输出,错误信息,和执行成功与否的结果。
Subprocess 提供了三个函数以不同的方式创建子进程。他们分别是
2.1 subprocess.call()
父进程等待子进程完成,并且返回子进程执行的结果 0/1 其实现方式
def call(*popenargs, **kwargs):
return Popen(*popenargs, **kwargs).wait()
例子
out=subprocess.call([“ls”, “-l”])
total 88
drwxr-xr-x 5 yangyi staff 170 1 25 22:37 HelloWorld
drwxr-xr-x 11 yangyi staff 374 12 18 2015 app
-rw-r–r-- 1 yangyi staff 3895 4 19 11:29 check_int.py
… 省略一部分
print out
0out=subprocess.call([“ls”, “-I”])
ls: illegal option – I
usage: ls [-ABCFGHLOPRSTUWabcdefghiklmnopqrstuwx1] [file …]print out
1
2.2 subprocess.check_call()
父进程等待子进程完成,正常情况下返回0,当检查退出信息,如果returncode不为0,则触发异常subprocess.CalledProcessError,该对象包含有returncode属性,应用程序中可用try…except…来检查命令是否执行成功。其实现方式
def check_call(*popenargs, **kwargs):
retcode = call(*popenargs, **kwargs)
if retcode:
cmd = kwargs.get(“args”)
raise CalledProcessError(retcode, cmd)
return 0
例子
out=subprocess.check_call([“ls”])
HelloWorld check_int.py enumerate.py hello.pyprint out
0out=subprocess.check_call([“ls”,’-I’]) #执行命令失败的时候回抛出CalledProcessError异常,并且返回结果1
ls: illegal option – I
usage: ls [-ABCFGHLOPRSTUWabcdefghiklmnopqrstuwx1] [file …]
Traceback (most recent call last):
File “”, line 1, in
File “/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py”, line 540, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command ‘[‘ls’, ‘-I’]’ returned non-zero exit status 1
2.3 subprocess.check_output()
和 subprocess.check_call() 类似,但是其返回的结果是执行命令的输出,而非返回0/1 其实现方式
def check_output(*popenargs, **kwargs):
process = Popen(*popenargs, stdout=PIPE, **kwargs)
output, unused_err = process.communicate()
retcode = process.poll()
if retcode:
cmd = kwargs.get(“args”)
raise CalledProcessError(retcode, cmd, output=output)
return output
例子
out=subprocess.check_output([“ls”]) #成功执行命令
print out
HelloWorld
check_int.py
enumerate.py
flasky
hello.pyout=subprocess.check_output([“ls”,"-I"])#执行命令出现异常直接打印出异常信息。
ls: illegal option – I
usage: ls [-ABCFGHLOPRSTUWabcdefghiklmnopqrstuwx1] [file …]
Traceback (most recent call last):
File “”, line 1, in
File “/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py”, line 573, in check_output
raise CalledProcessError(retcode, cmd, output=output)
subprocess.CalledProcessError: Command ‘[‘ls’, ‘-I’]’ returned non-zero exit status 1
通过上面三个例子,我们可以看出前面两个函数不容易控制输出内容,在使用subprocess包中的函数创建子进程执行命令的时候,需要考虑
在创建子进程之后,父进程是否暂停,并等待子进程运行。
如何处理函数返回的信息(命令执行的结果或者错误信息)
当子进程执行的失败也即returncode不为0时,父进程如何处理后续流程?
三 subprocess的核心类 Popen()
认真的读者朋友可以看出上面三个函数都是基于Popen实现的,为啥呢?因为 subprocess 仅仅提供了一个类,call(),check_call(),check_outpu()都是基于Popen封装而成。当我们需要更加自主的应用subprocess来实现应用程序的功能时,
我们要自己动手直接使用Popen()生成的对象完成任务。接下来我们研究Popen()的常见用法 ,详细的用法请参考官方文档
Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)
这里我们只要掌握常用的参数即可
args 字符串或者列表,比如 “ls -a” [“ls”,"-a"]
stdin/stdout/stderr 为None时表示没有任何重定向,继承父进程,还可以设置为PIPE 创建管道/文件对象/文件描述符(整数)/stderr 还可以设置为 STDOUT 后面会给出常见的用法
shell 是否使用shell来执行程序。当shell=True, 它将args看作是一个字符串,而不是一个序列。在Unix系统,且 shell=True时,shell默认使用 bin/sh.
如果 args是一个字符串,则它声明了通过shell执行的命令。这意味着,字符串必须要使用正确的格式。
如果 args是一个序列,则第一个元素就是命令字符串,而其它的元素都作为参数使用。可以这样说,Popen等价于:
Popen([’/bin/sh’, ‘-c’, args[0], args[1], …])
与上面第二部分介绍的三个函数不同,subprocess.Popen() fork子进程之后主进程不会等待子进程结束,而是直接执行后续的命令。当我们需要等待子进程结束必须使用wait()或者communicate()函数。举个例子,
import subprocess
sbp=subprocess.Popen([“ping”,"-c",“5”,“www.youzan.com”])
print “ping is not done”
从执行结果上看,子进程 ping命令并未执行完毕,subprocess.Popen() 后面的命令就开始执行了。
Popen常见的函数
Popen.poll() 用于检查子进程是否已经结束,设置并返回returncode属性。
Popen.wait() 等待子进程结束,设置并返回returncode属性。
Popen.communicate(input=None) 与子进程进行交互。向stdin发送数据,或从stdout和stderr中读取数据。可选参数input指定发送到子进程的参数。Communicate()返回一个元组:(stdoutdata, stderrdata)。注意:如果希望通过进程的stdin向其发送数据,在创建Popen对象的时候,参数stdin必须被设置为PIPE。同样,如果希望从stdout和stderr获取数据,必须将stdout和stderr设置为PIPE。需要注意的是 communicate()是Popen对象的一个方法,该方法会阻塞父进程,直到子进程完成。
Popen.send_signal(signal) 向子进程发送信号。
Popen.terminate() 终止子进程。
Popen.kill() 杀死子进程。
Popen.pid 获取子进程的进程ID。
Popen.returncode 获取进程的返回值,成功时,返回0/失败时,返回 1。如果进程还没有结束,返回None。
这里需要多做说明的是对于 wait()官方提示:
Warning This will deadlock when using stdout=PIPE and/or stderr=PIPE and the child process generates enough output to a pipe such that it blocks waiting for the OS pipe buffer to accept more data. Use communicate() to avoid that.
即当stdout/stdin设置为PIPE时,使用wait()可能会导致死锁。因而建议使用communicate而对于communicate,文档又给出:
Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate. The optionalinput argument should be a string to be sent to the child process, orNone, if no data should be sent to the child.communicate() returns a tuple (stdoutdata, stderrdata).
Note that if you want to send data to the process’s stdin, you need to create the Popen object with stdin=PIPE. Similarly, to get anything other thanNone in the result tuple, you need to give stdout=PIPE and/orstderr=PIPE too.
Note:The data read is buffered in memory, so do not use this method if the data size is large or unlimited.
communicate会把数据读入内存缓存下来,所以当数据很大或者是无限的数据时不要使用。那么坑爹的问题来了:当你要使用Python的subprocess.Popen实现命令行之间的管道传输,同时数据源又非常大(比如读取上GB的文本或者无尽的网络流)时,官方文档不建议用wait,同时communicate还可能把内存撑爆,我们该怎么操作?
四 Subprocess 和MySQL 的交互
纸上来得终觉浅,绝知此事要躬行。自动化运维需求中会有重启/关闭/备份/恢复 MySQL的需求。怎么使用Python的subprocess来解决呢?启动MySQL的命令如下
startMySQL="/usr/bin/mysqld_safe --defaults-file=/srv/my{0}/my.cnf --read_only=1 & ".format(port)
实际上使用child=subprocess.Popen(startMySQL,shell=True,stdout=stdout=subprocess.PIPE),子进程mysql_safe是无任何返回输出的,使用,child.communicate()或者读取stdout 则会持续等待。需要使用 child.wait()或者child.poll()检查子进程是否执行完成。
import subprocess,time
def startMySQL(port):
startMySQL="/usr/bin/mysqld_safe --defaults-file=/srv/my{0}/my.cnf --read_only=1 & ".format(port)
child=subprocess.Popen(startMySQL, shell=True,stdout=subprocess.PIPE)
child.poll()
time.sleep(3) #有些MySQL实例启动可能需要一定的时间
if child.returncode:
print “instance {0} startup failed …”.format(port)
else:
print “instance {0} startup successed …”.format(port)
return
测试
root@rac3:~/python# >python 1.py
instance 3308 startup successed …
subprocess模块使用
call
执行命令,返回状态码
ret = subprocess.call([“ls”, “-l”], shell=False)
ret = subprocess.call(“ls -l”, shell=True)
shell = True ,允许 shell 命令是字符串形式
check_call
执行命令,如果执行状态码是 0 ,则返回0,否则抛异常
subprocess.check_call([“ls”, “-l”])
subprocess.check_call(“exit 1”, shell=True)
check_output
执行命令,如果状态码是 0 ,则返回执行结果,否则抛异常
subprocess.check_output([“echo”, “Hello World!”])
subprocess.check_output(“exit 1”, shell=True)
subprocess.Popen(…)
用于执行复杂的系统命令
参数:
args:shell命令,可以是字符串或者序列类型(如:list,元组)
bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲
stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。
所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。
shell:同上
cwd:用于设置子进程的当前目录
env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
universal_newlines:不同系统的换行符不同,True -> 同意使用 \n
startupinfo与createionflags只在windows下有效
将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等
import subprocess
ret1 = subprocess.Popen([“mkdir”,“t1”])
ret2 = subprocess.Popen(“mkdir t2”, shell=True)
执行普通命令
终端输入的命令分为两种:
输入即可得到输出,如:ifconfig
输入进行某环境,依赖再输入,如:python
import subprocess
obj = subprocess.Popen(“mkdir t3”, shell=True, cwd=’/home/dev’,)
import subprocess
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 ')
obj.stdin.write('print 4 \n ')
obj.stdin.close()
cmd_out = obj.stdout.read()
obj.stdout.close()
cmd_error = obj.stderr.read()
obj.stderr.close()
print cmd_out
print cmd_error
说明:实际例子会报错
[root@redhat706 test]# ./test.py
Traceback (most recent call last):
File “./test.py”, line 7, in
obj.stdin.write(‘print 1’)
TypeError: a bytes-like object is required, not ‘str’
解决:
#将字符串转为字节的方法1:
str.encode(‘需转换的字符串’,‘utf-8’)
#将字符串转为字节的方法2:
bytes(‘需转换的字符串’,‘utf-8’)
Python3.11将信息写入文件的不报错方法
#写入文件(覆盖原有内容)
def WriteInfo(needWriteInfo,filePathAndName):
with open(filePathAndName,‘wb’) as fileObj:
tmpBytes = bytes(needWriteInfo,‘utf8’)
fileObj.write(tmpBytes)
更改为如下成功:
import subprocess
obj = subprocess.Popen([“python”], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
obj.stdin.write(bytes(‘print(1)\n’,‘utf-8’))
obj.stdin.write(bytes(‘printf(2)\n’,‘utf-8’))
obj.stdin.close()
cmd_out = obj.stdout.read()
obj.stdout.close()
cmd_error = obj.stderr.read()
obj.stderr.close()
print(cmd_out)
print(cmd_error)
输出结果
[root@redhat706 test]# ./test.py
b’1\n’
b’Traceback (most recent call last):\n File “
import subprocess
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 ')
obj.stdin.write('print 4 \n ')
out_error_list = obj.communicate()
print out_error_list
更改:
import subprocess
obj = subprocess.Popen([“python”], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
obj.stdin.write(bytes(‘print(1)\n’,‘utf-8’))
obj.stdin.write(bytes(‘print(2)\n’,‘utf-8’))
out_error_list=obj.communicate()
print(out_error_list)
结果返回一个元组
[root@redhat706 test]# ./test.py
(b’1\n2\n’, b’’)
import subprocess
obj = subprocess.Popen([“python”], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
obj.stdin.write(bytes(‘print(1)\n’,‘utf-8’))
obj.stdin.write(bytes(‘printf(2)\n’,‘utf-8’))
out_error_list=obj.communicate()
print(out_error_list)
错误结果
[root@redhat706 test]# ./test.py
(b’1\n’, b’Traceback (most recent call last):\n File “
import subprocess
obj = subprocess.Popen([“python”], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out_error_list = obj.communicate(‘print “hello”’)
print out_error_list
更改
import subprocess
obj = subprocess.Popen([“python”], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out_error_list=obj.communicate(bytes(‘print(1)\n’,‘utf-8’))
print(out_error_list)
操作mysql的例子
#!/usr/bin/python
import subprocess
input = input(‘Please input your password:’)
if input!=’’:
password=input
else:
exit(0)
obj = subprocess.Popen(“mysql -uroot -p”+password+" -Dtestdb -h10.10.122.84", stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,shell=True)
obj.stdin.write(bytes(‘select now();\n’,‘utf-8’))
obj.stdin.write(bytes(‘select * from test1;\n’,‘utf-8’))
obj.stdin.close()
cmd_out = obj.stdout.read()
obj.stdout.close()
cmd_error = obj.stderr.read()
obj.stderr.close()
print(cmd_out)
print(cmd_error)
The subprocess module allows you to spawn new processes, connect to their input/output/error pipes, and obtain their return codes. This module intends to replace several older modules and functions:
os.system
os.spawn*
The recommended approach to invoking subprocesses is to use the run() function for all use cases it can handle. For more advanced use cases, the underlying Popen interface can be used directly.
The run() function was added in Python 3.5; if you need to retain compatibility with older versions, see the Older high-level API section.
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, timeout=None, check=False)
Run the command described by args. Wait for command to complete, then return a CompletedProcess instance.
The arguments shown above are merely the most common ones, described below in Frequently Used Arguments (hence the use of keyword-only notation in the abbreviated signature). The full function signature is largely the same as that of the Popen constructor - apart from timeout, input and check, all the arguments to this function are passed through to that interface.
This does not capture stdout or stderr by default. To do so, pass PIPE for the stdout and/or stderr arguments.
The timeout argument is passed to Popen.communicate(). If the timeout expires, the child process will be killed and waited for. The TimeoutExpired exception will be re-raised after the child process has terminated.
The input argument is passed to Popen.communicate() and thus to the subprocess’s stdin. If used it must be a byte sequence, or a string if universal_newlines=True. When used, the internal Popen object is automatically created withstdin=PIPE, and the stdin argument may not be used as well.
If check is True, and the process exits with a non-zero exit code, a CalledProcessError exception will be raised. Attributes of that exception hold the arguments, the exit code, and stdout and stderr if they were captured.
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.run(…)是推荐的常用方法,在大多数情况下能满足需求,但如果你可能需要进行一些复杂的与系统的交互的话,你还可以用subprocess.Popen(),语法如下:
p = subprocess.Popen(“find / -size +1000000 -exec ls -shl {} ;”,shell=True,stdout=subprocess.PIPE)
print(p.stdout.read())
可用参数:
args:shell命令,可以是字符串或者序列类型(如:list,元组)
bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲
stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。
所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。
shell:同上
cwd:用于设置子进程的当前目录
env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
universal_newlines:不同系统的换行符不同,True -> 同意使用 \n
startupinfo与createionflags只在windows下有效
将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等
终端输入的命令分为两种:
输入即可得到输出,如:ifconfig
输入进行某环境,依赖再输入,如:python
需要交互的命令示例
先在同一个文件夹下创建两个.py文件。
第一个:13.py
-- coding: utf-8 --
author = “YuDian”
‘’’
multiprocessing->Pool进程池。
file name:13.py
‘’’
from multiprocessing import Pool
import os, time, random
def long_time_task(name):
print(‘Run task %s (%s)…’ % (name, os.getpid()))
start = time.time()
time.sleep(random.random() * 3)
end = time.time()
print(‘Task %s runs %0.2f seconds.’ % (name, (end - start)))
if name == ‘main’:
print(‘Parent process %s.’ % os.getpid())
print(‘父进程的父进程:(也就是打开这个文件的进程):’,os.getppid())
p = Pool(9) # pool()可以指定同时运行的进程数。如果缺省,默认为该电脑的CPU核数。如果赋值超过CPU核数,按照CPU核数。
for i in range(11): # range()内的范围可以任意指定,为运行的进程总数。
p.apply_async(long_time_task, args=(i,))
print(‘Waiting for all subprocesses done…’)
p.close()
p.join()
print(‘All subprocesses done.’)
第二个: 14.py
import subprocess
import os
‘’’
开一个子进程,并对子进程通信。参考:http://blog.csdn.net/seetheworld518/article/details/48805261
file name:14.py
‘’’
class Shell(object):
def runCmd(self, cmd):
res = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
print(‘本程序的进程2:’,os.getpid())
print(‘用res.pid得到的就是这个的子进程,也就是13.py的父进程’,res.pid)
sout, serr = res.communicate(‘13.py\n’)
print(‘本程序的进程3:’,os.getpid())
return res.returncode, sout, serr, res.pid
print(‘本程序的进程1:’,os.getpid())
shell = Shell()
result=shell.runCmd(‘python F:/python_codes/learn_python_of_simple_codes/demos/13.py’)
print(result[1].decode(‘utf-8’))
最后输出为:
本程序的进程1: 13928
本程序的进程2: 13928
用res.pid得到的就是这个的子进程,也就是13.py的父进程 6908
本程序的进程3: 13928
Parent process 8720.
父进程的父进程:(也就是打开这个文件的进程): 6908
Waiting for all subprocesses done…
Run task 0 (15352)…
Run task 1 (7832)…
Run task 2 (11824)…
Run task 3 (3140)…
Run task 4 (12572)…
Run task 5 (18808)…
Run task 6 (9284)…
Run task 7 (17996)…
Run task 8 (1996)…
Task 5 runs 0.33 seconds.
Run task 9 (18808)…
Task 6 runs 0.63 seconds.
Run task 10 (9284)…
Task 7 runs 1.27 seconds.
Task 10 runs 0.90 seconds.
Task 2 runs 2.32 seconds.
Task 9 runs 2.07 seconds.
Task 0 runs 2.46 seconds.
Task 1 runs 2.47 seconds.
Task 4 runs 2.51 seconds.
Task 3 runs 2.58 seconds.
Task 8 runs 2.82 seconds.
All subprocesses done.




