关于subprocess.popen模块相关知识点总结

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


注意下面
如果有车载讨论需要的小伙伴,可以私信加我微信,拉你进群,和同行业大佬交流
注意上面

前言

最近在配置集成测试工具,在拉起三方组件和调用adb方面需要用到subprocess.popen模块,今天做个总结记录,方便以后查询


二、使用步骤

1.将子进程返回值存储到本地环境

代码如下(示例):

    def __start_logcat(self, path, package='IntegrationTest'):
        """
        功能:打开logcat日志存储
        """
        file_path = path + '\\' + 'logcat.txt'
        self.__log_file = open(file_path, 'w')
        if self.__log_process is None:
            instruct = 'adb logcat -s "{}"'.format(package)
            self.__log_process = sp.Popen(instruct, stdout=self.__log_file, stdin=sp.PIPE, stderr=sp.PIPE)  # 将stdout数据直接输出到本地文件中
        else:
            self.__log_process.terminate()
            self.__log_process.wait()
            if self.__log_process is not None:
                self.__log_file.close()
            file_path = path + '\\' + 'logcat.txt'
            self.__log_file = open(file_path, 'w')
            instruct = 'adb logcat -s "{}"'.format(package)
            self.__log_process = sp.Popen(instruct, stdout=self.__log_file, stdin=sp.PIPE, stderr=sp.PIPE)

2.继续向Popen对象中输入指令

代码如下(示例):

    def start_app(self,filepath):
        """
        功能:打开freemaster应用
        参数1:项目文件路径
        """
        path_list = os.path.split(filepath)
        disk = filepath.split("\\")[0]      # 获取盘符信息
        path = "cd " + path_list[0]     # 获取文件路径
        file = path_list[1]     # 获取文件名信息
        commands = (disk + '\n' +
                    path + '\n'
                    + file + '\n'
                    )
        process = sp.Popen('cmd', stdout=sp.PIPE, stdin=sp.PIPE, stderr=sp.PIPE)
        process.communicate(commands.encode('gbk'))    # 通过communicate输入,只能输入一次,可以得到返回值,gbk是防止有中文编码
        process.terminate()
        state = process.wait()
        return state

还有一种方案就是process.stdin.write(data.encode('gbk'))

3.断开管道连接

代码如下(示例):

import subprocess as sp
def __start_socket():
    """
    功能:开启socket通讯
    """
    Socket_process = sp.Popen('adb shell am start-foreground-service com.hsae.mysocketservice', stdout=sp.PIPE, stdin=sp.PIPE,
                                     stderr=sp.PIPE)
    result = Socket_process.stdout.read().decode('utf-8')
    Socket_process.communicate()
    print(result)
    print("123")

    app = sp.Popen('adb shell am start-foreground-service com.hsae.mysocketservice', stdout=sp.PIPE, stdin=sp.PIPE,
                                    stderr=sp.PIPE)
    result = app.stdout.read().decode('utf-8')
    app.communicate()
    print(result)

__start_socket()

当有多个线程与stdin,stdout,stderr管道相连时communicate()也会断开当前线程的管道连接

4.通过CTRL C结束子进程

os.kill(0, signal.CTRL_C_EVENT)		# 这个指令会结束所有与子进程相关的子进程和父进程,其实不建议使用的,会报异常

总结

当我们用可迭代对象时一定要注意不要多个程序同时对一个可迭代对象进行操作,这样会出现获取的数据错乱问题,今天特此记录,防止后面忘记。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值