python实现批量运行命令行

背景:

对于不同参数设置来调用同一个接口,如果手动一条条修改再运行非常慢且容易出错。尤其是这次参数非常多且长。比如之前都是输入nohup python -u exe.py >> ../log/exp3.log 2>&1 & 来运行一次,在exe中会设置参数并调用接口运行preditction_uni(input_file_path, sheet_name, output_file_path, pic_path, cols_x, cols_y, n_jobs, sheet_name_res),由于每次这些参数都不同但又有一定的规律,所以可以尝试批量运行。

解决方法:

使用python的subprocess

文件结构是:

|--cmd_exe.py

--exe.py

--exp3.py

--interface.py

exp3.py中设置参数并调用interface.py中的接口,exe.py中是主函数调用exp3.py启动运行。

现在修改了exp3.py中代码,循环的使用不同参数来带入subprocess,进而调用cmd_exe.py执行原本要在terminal中执行的指令。这样把原本在exp3.py中调用接口preditction_uni部分挪到新的cmd_exe.py中,exp3,py中增加command循环调用的代码来实现批量执行。

# exp3.py 部分代码

import subprocess
# ...
# 设置参数
# ···
n_jobs = int(5)
cols_x_str = f'"{cols_xs}"' commmand = f"nohup python -u cmd_exe.py {input_file_path} {sheet_name} {output_file_path} {pic_path} {cols_x_str} {cols_y} {n_jobs} {sheet_name_res} >> ../log/exp3/{log_name}.log 2>&1 &" print(commmand) # 一般会打印命令
subprocess.Popen(commmand, shell=True)
# cmd_exe.py 代码

import sys
import exp3
import ast if __name__ == '__main__':
input_file_path = sys.argv[1]
sheet_name = sys.argv[2]
output_file_path = sys.argv[3]
pic_path = sys.argv[4]
cols_x = ast.literal_eval(sys.argv[5])
cols_y = sys.argv[6]
n_jobs = sys.argv[7]
sheet_name_res = sys.argv[8] exp3.preditction_uni(input_file_path, sheet_name, output_file_path, pic_path, cols_x, cols_y, n_jobs, sheet_name_res)
  • 传参数问题1:

    exp3.py中我想传给调用的preditction_uni函数参数有数字和包含多个字符串的数组。示例如下。

    n_jobs = 5
    cols_xs = ['参数1', '参数2','参数1', '参数2','参数1', '参数2']

    但是在执行后会出现错误:

    Traceback (most recent call last):
    File "/home/P.py", line 11, in <module>
    cols_x = ast.literal_eval(sys.argv[5])
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "/home/anaconda3/envs/python310/lib/python3.11/ast.py", line 64, in literal_eval
    node_or_string = parse(node_or_string.lstrip(" \t"), mode='eval')
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "/home/anaconda3/envs/python310/lib/python3.11/ast.py", line 50, in parse
    return compile(source, filename, mode, flags,
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "<unknown>", line 1
    [参数1,
    ^
    SyntaxError: '[' was never closed

    尝试使用ast.literal_eval()来解析,但是不行。cols_xs 是一个包含多个字符串元素的列表。通过argv来传递字符串列表是解析出来只有第一个元素。所以想把整个字符串列表都传过来那么要把整个列表作为一个字符串,即在外面再包一个双引号f'"{cols_xs}"'

  • 传参数问题2:

    Traceback (most recent call last):
    ...
    File "/home/P.py", line 179, in post_run
    y_pred_test, y_pred_prob_test, b_solver, b_c = train_model_Grid(estimator, param, cv=5, X_train=X_train_std, X_test=X_test_std, y_train=y_train, n_jobs=n_jobs)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...
    validate_parameter_constraints
    raise InvalidParameterError(
    sklearn.utils._param_validation.InvalidParameterError: The 'n_jobs' parameter of GridSearchCV must be an instance of 'int' or None. Got '5' instead.

    传的参数是一个字符串类型,即使它表示一个整数值。使用n_jobs = int(5)

    通过 sys.argv 传递的参数是字符串类型(str)。sys.argv 是一个列表,其中包含了命令行参数的字符串表示形式。列表的第一个元素是执行 Python 脚本的文件路径,后续元素是命令行中提供的参数。

    如果需要将其解析为其他类型,例如整数或浮点数,需要使用相应的转换函数(例如 int()float())进行转换。

sys传参数

通过 sys.argv 传递的参数是字符串类型(str)

示例程序:

# test.py

import subprocess
import test1 nums = [1, 2, 3] input_file_path = '../python/data' n_jobs = 6 col_x =[
['test', 'is', 'just', 'a', 'demo'],
['tomorrow', 'never', 'wait', 'for', 'you'],
['just', 'do', 'it', 'now']
] cols = zip(nums, col_x) for num, colx in cols:
# colx = f'"{colx}"'
command = f"python -u test1.py {input_file_path} {n_jobs} {colx} >> ./test.log 2>&1 &" print(command) subprocess.Popen(command, shell=True) print(f"process {num} is running")
# test1.py
import sys if __name__ == '__main__': print(f"sys.argv[0] = {sys.argv[0]} , type = {type(sys.argv[0])}")
print(f"sys.argv[1] = {sys.argv[1]} , type = {type(sys.argv[1])}")
print(f"sys.argv[2] = {sys.argv[2]} , type = {type(sys.argv[2])}")
print(f"sys.argv[3] = {sys.argv[3]} , type = {type(sys.argv[3])}")
python test.py

结果:

python -u test1.py ../python/data 6 ['test', 'is', 'just', 'a', 'demo'] >> ./test.log 2>&1 &
process 1 is running
python -u test1.py ../python/data 6 ['tomorrow', 'never', 'wait', 'for', 'you'] >> ./test.log 2>&1 &
process 2 is running
python -u test1.py ../python/data 6 ['just', 'do', 'it', 'now'] >> ./test.log 2>&1 &
process 3 is running # test.log
sys.argv[0] = test1.py , type = <class 'str'>
sys.argv[1] = ../python/data , type = <class 'str'>
sys.argv[2] = 6 , type = <class 'str'>
sys.argv[3] = [tomorrow, , type = <class 'str'>
sys.argv[0] = test1.py , type = <class 'str'>
sys.argv[1] = ../python/data , type = <class 'str'>
sys.argv[2] = 6 , type = <class 'str'>
sys.argv[3] = [test, , type = <class 'str'>
sys.argv[0] = test1.py , type = <class 'str'>
sys.argv[1] = ../python/data , type = <class 'str'>
sys.argv[2] = 6 , type = <class 'str'>
sys.argv[3] = [just, , type = <class 'str'>

在 command 之前增加colx = f'"{colx}"',之后的效果:

# test.log

sys.argv[1] = ../python/data , type = <class 'str'>
sys.argv[2] = 6 , type = <class 'str'>
sys.argv[3] = ['test', 'is', 'just', 'a', 'demo'] , type = <class 'str'>
sys.argv[0] = test1.py , type = <class 'str'>
sys.argv[1] = ../python/data , type = <class 'str'>
sys.argv[2] = 6 , type = <class 'str'>
sys.argv[3] = ['tomorrow', 'never', 'wait', 'for', 'you'] , type = <class 'str'>
sys.argv[0] = test1.py , type = <class 'str'>
sys.argv[1] = ../python/data , type = <class 'str'>
sys.argv[2] = 6 , type = <class 'str'>
sys.argv[3] = ['just', 'do', 'it', 'now'] , type = <class 'str'>

python实现批量运行命令行的更多相关文章

  1. python如何通过windows命令行运行一个python程序文件?

    python如何通过windows命令行运行一个python程序文件? cmd 进入到py文件对应目录下或者直接在上面的文件地址栏输入cmd,敲入回车 定位到对应的目录下 输入python xxx.p ...

  2. [Java][Android][Process] 分享 Process 运行命令行封装类型

    我在以前的文章中提到,使用Java不会有一个问题,创建运行命令来创建太多进程后创建进程行语句. [Android] ProcessBuilder与Runtime.getRuntime().exec分别 ...

  3. Python通过调用windows命令行处理sam文件

    Python通过调用windows命令行处理sam文件 以samtools软件为例 一.下载或者索取得到windows版本的samtools软件,解压后如下: 进入文件内部,有如下几个文件: 二.将s ...

  4. python开发简单的命令行工具

    介绍 Python模块argparse,这是一个命令行选项,参数和子命令的解释器,使用该模块可以编写友好的命令行工具,在程序中定义好需要的参数,argparse将弄清楚如何解析 sys.argv中的参 ...

  5. [Java][Android][Process] 暴力的服务能够解决一切,暴力的方式运行命令行语句

    不管是在Java或者Android中运行命令行语句殊途同归都是创建一个子进程运行调用可运行文件运行命令.类似于Windows中的CMD一样. 此时你有两种方式运行:ProcessBuilder与Run ...

  6. Windows 右键快速运行命令行

    原文见:右键命令行 - yacper - 博客园 方法一:配置文件夹选项 1 打开人任意文件夹,[工具] --> [文件夹选项] --> [文件类型] --> [(无)资料夹] -- ...

  7. 将Python模块转变为命令行工具

    问:如何输入命令行就能执行python代码呢? 答:要将python模块转变为命令行工具只用在 setup.py 文件中添加参数entry_points 例如: entry_points={ 'con ...

  8. 文件批量加密重命名--python脚本AND mysql命令行导入数据库

    在考试中学生交上来的报告,需要进行一下文件名加密,这样阅卷老师就不知道是谁的报告了 在百度帮助下,完成了加密和解密脚本, 加密 #!/usr/bin/python # -*- coding: utf- ...

  9. Python 的几个命令行参数

    1) 以 $ python 方式启动 python 解释器,之后 import 一个模块,将生成 .pyc 文件. 2) 以 $ python -O 方式启动 python 解释器,之后 import ...

  10. 简明Python教程自学笔记——命令行通讯录

    [前言]学习Python已经有一段时间了,相关的书籍资料也下载了不少,但是没有一本完整的看完,也没有编出一个完整的程序.今天下午比较清闲就把<简明Python教程>看了一遍,然后根据书里面 ...

随机推荐

  1. 【framework】应用进程启动流程

    1 前言 Activity启动流程 中介绍了从点击桌面上应用快捷方式到 Activity 的 onCreate() 方法调用流程,本将介绍应用进程的启动流程.由于应用进程启动流程复杂,本文按进程将其拆 ...

  2. Js中Number对象

    Js中Number对象 JavaScript的Number对象是经过封装从而能够处理数字值的对象,Number对象由Number()构造器以及字面量声明的值在转化为包装对象时创建,JavaScript ...

  3. Swoole从入门到入土(12)——HTTP服务器[Response]

    继上一节了解完请求对象之后,这一节我们着重了解响应对象(Response).响应对象主要用于将数据发现到客户端.当 Response 对象销毁时,如果未调用 end 发送 HTTP 响应,底层会自动执 ...

  4. 关于 try... catch

    在逛论坛看见一个有意思的帖子,有点意思,记录下 关于"异常捕捉"(try catch)是否存在悖论? 一些我觉得有用的回复,放到下面了, 1. 当某些错误状况难以完全避免时,try ...

  5. error接口

    // 实际上它是interface类型,这个类型有一个返回错误信息的单一方法: type error interface{ Error() string } 创建一个error最简单的方法就是调用er ...

  6. celery中异步延迟执行任务apply_anysc的用法

    描述 首先说下异步任务执行delay()和apply_anysc()两者区别,其实两者都是执行异步任务的方法,delay是apply_anysc的简写.所以delay中传递的参数会比apply_any ...

  7. hibernate-delete(Entity)的顺序问题

    hibernate为我们提供了删除直接根据实体参数删除数据的方法: HibernateTemplate().delete(entity); public void delete(final Objec ...

  8. 【Azure K8S】演示修复因AKS密钥过期而导致创建服务不成功的问题(The provided client secret keys for app ****** are expired)

    问题描述 在Azure Kubernetes 服务中,创建一个Internal Load Balancer服务,使用以下yaml内容: internallb.yaml apiVersion: v1 k ...

  9. JVM解析

    synize锁升级

  10. matlab修改读取mat文件后的变量名

    代码如下: %% str1=load('CH1.mat'); val_names = fieldnames(str1); % 获取结构体后那个未知的变量名 data1 = getfield(str1, ...