python里运行linux命令

使用版本:python3.9,centos7.8

python里提供了os模块,可以让我在代码中对linux发送命令,并获取返回值。

这里会讲到两种方法去使用os模块----os.popen和os.system

一.  os.system

os.system('命令字符串')。这个命令适用于一些你只需要知道结果是否成功的命令,因为它只会返回给你一个int类型的数字,0代表成功,非0代表失败。而且当你的命令字符串是一个子进程命令的话,他的返回值并不准确,他不会等待子进程在后台运行结束,只要子进程能够进入运行状态,他就会返回0。

二.  os.popen

在我看来,这个方法在使用子进程做并行或者在获取返回结果上,是很好用的,首先它一共有3个参数,

cmd--命令

mode--方式(认值为‘r’,可选值为‘w’,一般场景中,r的使用比较普遍)

buffering--缓存值,认为-1

方法调用了subprocess里的方法,并最后帮助你关闭了资源,一条龙服务还是很人性化的。所以一般使用时,传一个命令即可,然后它提供了read(),readlines()给你去拿到返回值

即os.popen('cmd').read()

而且笔者认为它强大之处在于,当cmd是一个后台进程,即在命令最后加入&符号的进程,它依旧会等待进程结束并拿到返回值,我也用他帮我将原本需要5分钟+的程序中,加上使用子进程并行将时间缩短到20秒左右。

话不多说,分享实战经验,一个读取jenkins信息并写入时序数据库的流程:

获取相关信息,并发送请求方法

        if action == 'jenkins':
            # 获取主机地址
            host = request.get_host()
            response_data = {'kind': 'JenkinsInfo.get', 'msg': 'jenkins任务构建信息入库', 'status': 200, 'param': ''}
            data = request.GET
            jenkins_name = data.get('jenkins_name', '')
            if jenkins_name in JENKINS.keys():
                jenkins_info = JENKINS[jenkins_name]
            else:
                response_data.update({
                    'param': '参数无效',
                    'status': 403
                })
                return JsonResponse(response_data, status=response_data['status'])
            # 连接jenkins
            server = self.to_jenkins(jenkins_info)
            all_jobs = server.get_jobs()
            job_name_list = [x.get('name') for x in all_jobs]
            cmdb_job = {}
            # 获取cmdb中的app_name
            cmdb_apps = AppBasisNew.objects.filter(**{'status': '已上线'}).values('app_name')
            app_name_list = [x.get('app_name') for x in cmdb_apps]
            # 判断cmdb中app是否在jenkins中
            env_list = ['archive-PRE-', 'PRE-', 'bak-PRE-', 'ARCHIVE-PRE-', 'BAK-PRE-']
            if app_name_list and job_name_list:
                for app_name in app_name_list:
                    for env in env_list:
                        if env+app_name in job_name_list:
                            cmdb_job[env+app_name] = app_name
            if cmdb_job:
                job_str = str(cmdb_job).replace("{'", "").replace("'}", "").replace("', '", " ").replace("': '", "\|")
                res = os.popen(f"for job in {job_str}; do curl -G http://{host}/jenkins/pre/to_db?"f"jenkins_name={jenkins_name}\&job_name=$job & done").read()
                res_str = res.replace('}{', '}, {').join('[]')
                res_json = json.loads(res_str)
                response_data.update({
                    'param': res_json
                })
            else:
                response_data.update({
                    'param': 'jenkins与cmdb无匹配数据'
                })
            return JsonResponse(response_data, status=response_data['status'])

接受请求,返回相应:

        if action == 'to_db':
            data = request.GET
            jenkins_name = data['jenkins_name']
            job_name = data['job_name'].split('|')[0]
            project_name = data['job_name'].split('|')[1]
            server = self.to_jenkins(JENKINS[jenkins_name])
            build_info_list = []
            # 最新jenkins项目的构建时间
            last_timestamp = 0
            # 连接influxdb
            db_client = self.to_influxdb()
            try:
                job_info = server.get_job_info(job_name)
            except jenkins.JenkinsException:
                db_client.close()
                return JsonResponse({f'{jenkins_name}': f'{job_name} fail'})
            if job_info.get('builds'):
                # 获取该工程名每次构筑的时间:
                res = db_client.query(f"select max(build_time) from pre_job_info "
                                      f"where project_name::tag='{project_name}' and from_jenkins='{jenkins_name}'")
                last_time = 0
                if res:
                    last_time = [x[u'max'] for x in res.get_points()][0]
                for job_build in range(1, len(job_info['builds'])+1):
                    job_time = job_info['builds'][-job_build]['number']
                    try:
                        build_info = server.get_build_info(job_name, job_time)
                    except jenkins.JenkinsException:
                        db_client.close()
                        return JsonResponse({f'{jenkins_name}': f'{job_name} fail'})
                    if build_info.get('timestamp') // 1000 <= last_time:
                        break
                    if job_build == 1:
                        last_timestamp = build_info.get('timestamp')//1000
                    build_info_dict = ToDict().return_dic(build_info)
                    # 控制台输出
                    build_output = server.get_build_console_output(job_name, job_time)
                    build_out_list = build_output.split('\n')
                    build_agent_name = 'null'
                    project_path = 'null'
                    if jenkins_name == 'JENKINS_PRE1' or jenkins_name == 'JENKINS_PRE3':
                        res_info = ''
                        for i in build_out_list:
                            if 'Running on' in i:
                                res_info = i
                        if res_info:
                            build_agent_name = res_info.split()[-3]
                            project_path = res_info.split()[-1]
                    if jenkins_name == 'JENKINS_PRE2':
                        project_path = build_out_list[1].split()[-1]
                        build_agent_name = build_info_dict.get('builtOn')
                    if job_info.get('lastStableBuild'):
                        last_stable_build = job_info['lastStableBuild']['number']
                    else:
                        last_stable_build = 0
                    if job_info.get('lastSuccessfulBuild'):
                        last_successful_build = job_info['lastSuccessfulBuild']['number']
                    else:
                        last_successful_build = 0
                    if build_info_dict.get('actions_lastBuiltRevision_branch_name'):
                        build_branch_name = build_info_dict.get(
                            'actions_lastBuiltRevision_branch_name')
                        code_version = build_info_dict.get(
                            'actions_lastBuiltRevision_branch_SHA1')
                    else:
                        build_branch_name = build_info_dict.get('changeSet_revisions_module', 'null')
                        code_version = str(build_info_dict.get('changeSet_revisions_revision', 'null'))
                    if build_info_dict.get('result') == 'SUCCESS':
                        build_successful = True
                    else:
                        build_successful = False
                    if build_info_dict.get('actions_parameters_name1') == 'Fabu_Type':
                        fabu_type = build_info_dict.get('actions_parameters_value1')
                    else:
                        fabu_type = build_info_dict.get('actions_parameters_value2', 'all-in-one')
                    res = {'measurement': 'pre_job_info',
                           'tags': {
                               'project_name': project_name,
                               'build_result': build_info_dict.get('result'),
                               'project_path': project_path
                           },
                           'time': datetime.fromtimestamp(build_info_dict.get('timestamp') // 1000),
                           'fields': {
                               'build_agent_name': build_agent_name,
                               'build_branch_name': build_branch_name,
                               'build_causer': build_info_dict.get('actions_causes_userName'),
                               'build_exec_time': build_info_dict.get('duration') // 1000,
                               'build_measured_time': int(datetime.Now().timestamp()),
                               'build_number': build_info_dict.get('id'),
                               'build_result': build_info_dict.get('result'),
                               'build_result_ordinal': build_info_dict.get('queueId'),
                               'build_scheduled_time': build_info_dict.get('estimatedDuration') // 1000,
                               'build_status_message': build_info_dict.get('building'),
                               'build_successful': build_successful,
                               'build_time': build_info_dict.get('timestamp') // 1000,
                               'last_stable_build': last_stable_build,
                               'last_successful_build': last_successful_build,
                               'project_build_health': job_info['healthReport'][0]['score'],
                               'project_name': project_name,
                               'project_path': project_path,
                               'Code_Version': code_version,
                               'Fabu_Type': fabu_type,
                               'from_jenkins': jenkins_name
                           },
                           }
                    build_info_list.append(res)
            if build_info_list:
                db_client.write_points(build_info_list)
            else:
                db_client.close()
                return JsonResponse({f'{jenkins_name}': f'{job_name} has no new data'})
            # 数据入库验证
            new_res = db_client.query(f"select build_number from pre_job_info "
                                      f"where project_name::tag='{project_name}' and build_time={last_timestamp}")
            if new_res:
                db_client.close()
                return JsonResponse({f'{jenkins_name}': f'{job_name} success'})
            db_client.close()
            return JsonResponse({f'{jenkins_name}': f'{job_name} fail'})

相关文章

基础环境、流程图1)流程图jenkinspipeline发布应用2)、jenki...
本节是建立在流水线入门内容的基础上,而且,应当被当作一个...
Linuxcentos7安装Jenkins(jenkins-2.227-1.1.noarch.rpm)时遇...
作为一个拥有很多账号的当代美少女,忘记用户名密码什么的是...
Jenkins、GitLab和Maven(Nexus)完成自动构建迈向持续集成持...
 下载文档https://www.jenkins.io/zh/download/  Debian下...