python 执行非python程序

本文介绍Python中os模块及subprocess32模块的基本使用方法,包括执行系统命令、进程管理和从数据库读取数据等内容。

1. os模块

一些常见的函数:

# 获得系统信息
os.uname()
('Linux', 'sjpt-hdwxnew-33.wxxdc', '4.4.0-142-generic', '#168-Ubuntu SMP Wed Jan 16 21:00:45 UTC 2019', 'x86_64')
# 获得现在进程的真正用户
os.getuid()
1000
# 获得现在的PID
os.getpid()


1.1 system(cmd)

接受字符串形式的系统命令并执行它,执行命令时,python是挂起的,执行完毕后,会以system()的返回值形式给出退出状态(0:成功,非0:错误),python也将继续执行。

import os
os.system("cat ./tt.py")
result = os.system("uname -a")

1.2 exec*()

execl(file,arg0,arg1,...) : 用参数列表arg0,arg1等执行文件

execv(file,arglist) : 用参数向量列表执行文件

1.3. fork()

称为进程的单一执行流程控制,通常与ecec*()一起使用

调用fork()的原始进程称为父进程,该调用结果新创建的进程称为子进程。

两者区别:子进程永远返回0,父进程永远返回子进程的PID,且两个进程都会在调用fork() 后立即执行。

创建子进程的目的是为了让其运行其他程序,所以必须在父进程和子进程返回时采取分流。

fork() 会返回两次

import os
res = os.fork()
print(res)
if res == 0:
    print("sub process")
else:
    print("main process")
# 运行结果:
29335
main process
0
sub process

子进程自身有虚拟内存空间的拷贝,也有一份父进程地址空间的原样拷贝

1.4 wait*()

当子进程执行完毕,需要其父进程进行扫尾工作,亦称“收获孩子”,父进程可以继续运行,稍后扫尾也可以等待子进程完成并在那进行扫尾。

当子进程完成执行,还没有被收获的时候,就进入了闲置状态,变成僵尸进程,其仍然保留着存活时期分配给他们的系统资源,直到被父进程收获。

调用wait()会挂起执行,直到子进程执行完毕或通过信号终止。

waitpid() 还可以等待指定PID的子进程完成。

通常和fork(),exec*()一起使用

1.5 spawn*()

函数spawn*()家族和fork, exec*()相似,他们都在新进程中执行命令,类似于在线程中启动函数。

1.6 popen()

popen(cmd,mode='r',buffering=-1)

执行字符串命令,返回一个文件对象。

# 查看当前目录下的文件
import os
with os.popen('ls ./') as f:
    for line in f:
        print(line,)

2. subprocess32 模块

可以取代os模块的所有函数

2.1 call()

用于取代 os.system()

subprocess.call(args, *, stdin= None, stdout = None, stderr = None, shell = False) 
运行由args参数提供的命令,等待命令执行结束并返回返回码。args参数由字符串形式提供且有多个命令参数时,需要提供shell=True参数。

from subprocess32 import call

# 查看当前目录
res = call(('ls', '-l', '.'))
call('python run.py', shell=True, stdin=open('fake_input', 'r'), stdout=open('result', 'w'))

2.2 check_call()

与call方法类似,不同在于如果命令行执行成功,check_call返回返回码0,否则抛出subprocess.CalledProcessError异常。

import subprocess32
try:
    res = subprocess.check_call(['ls', '('])
    print('res:', res)
except subprocess32.CalledProcessError as exc:
    print('子进程的退出码:', exc.returncode)
    print('子进程的执行命令:', exc.cmd)
    print('output:', exc.output)

注意:不要为stdout和stderr参数赋值为subprocess32.PIPE

2.3 check_output()

在子进程执行命令,以字符串形式返回执行结果的输出。如果子进程退出码不是0,抛出subprocess.CalledProcessError异常。

import subprocess32
try:
    res = subprocess32.check_output('ls xxx',
                    stderr = subprocess.STDOUT,
                    shell = True)
    print('res:', res)
except subprocess.CalledProcessError as exc:
    print('returncode:', exc.returncode)
    print('cmd:', exc.cmd)
    print('output:', exc.output)

2.4 subprocess32.Popen类

from subprocess32 import Popen, PIPE, STDOUT
with Popen(('uname', '-a'), stdout=PIPE, stderr=STDOUT
    ,shell=True, close_fds=True).stdout as f:
#with Popen(('ls', '-l', '.'), stdout=PIPE).stdout as f:
    for line in f:
        print(line)

从数据库中读数据

2.4.1 hive sql 方式

def fetch_results(sql, table_title):
    command = """
         hive -S -e "
         set hive.cli.print.header=false;
         set mapreduce.job.queuename = root.hailangshiyebu-jishubu.default;
         %s "
    """ % (sql)
    result = []
    result.append(table_title)
    p = Popen(args=command, shell=True, stdout=PIPE)
    if p.poll() != 0:  # status = p.returncode
        print("执行失败" + str(status))
        sys.exit(1)
    for item in p.stdout.readlines():
        if  item.strip():
            line = item.split("\t")
            result.append(line[0])
    # out, err = p.communicate()
    return ''.join(result)

https://blog.youkuaiyun.com/MusicDancing/article/details/11675051621

2.4.2 spark sql 方式

import subprocess
from tempfile import NamedTemporaryFile

sql = 'select count(1) from table_name;'
# 临时文件
sql_file = NamedTemporaryFile('w+t',delete=False)
sql_file.write(sql)
sql_file.close()

cmd = """
    spark-sql --master yarn
        --queue root.bigdata
        --name 'xx'
        --executor-memory 8g
        --executor-cores 4
        --num-executors 50
        -f {file_name}
""".format(file_name=sql_file.name)
result = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值