1 python命令行参数
1.1 基本语法
一、代码use.py
import sys
print("脚本名:",sys.argv[0])
print("参数1:",sys.argv[1])
二、命令行python3 use.py “lucy”
脚本名: use.py
参数1: lucy
1.2 宿主机实例
将json字符串作为命令行参数传递。
1.2.1 use.py
# -*- coding: UTF-8 -*-
import sys
if __name__ == "__main__":
print("receive",sys.argv[1])
1.2.2 main.py
# -*- coding: UTF-8 -*-
import subprocess
import json
data_dict = {'name':'lucy'}
data_json = json.dumps(data_dict, separators=(',', ':')) # 去掉格式化后的空格
cmd_str = "python use.py {}".format(data_json)
print(cmd_str)
re = subprocess.getoutput(cmd_str)
print(re)
输出如下:
python use.py {"name":"lucy"}
receive {name:lucy}
sys.argv会对输入的参数进行转义,传递的双引号被自动删除。
1.3 命令行传递json
1.3.1 use.py
# -*- coding: UTF-8 -*-
import sys
if __name__ == "__main__":
print("receive",sys.argv[1])
1.3.2 main.py
# -*- coding: UTF-8 -*-
# -*- coding: UTF-8 -*-
import subprocess
import json
data_dict = {'name':'lucy',
"starttime":"2022-11-14 07:20:23.654"}
data_json = json.dumps(data_dict) # 第一次序列化
print("第一次序列化",data_json)
data_json = json.dumps(data_json) # 第二次序列化,加上转义字符
print("第二次序列化",data_json)
cmd_str = "python use.py {}".format(data_json)
print(cmd_str)
re = subprocess.getoutput(cmd_str)
print("GET",re)
输出如下:
第一次序列化 {"name": "lucy", "starttime": "2022-11-14 07:20:23.654"}
第二次序列化 "{\"name\": \"lucy\", \"starttime\": \"2022-11-14 07:20:23.654\"}"
python use.py "{\"name\": \"lucy\", \"starttime\": \"2022-11-14 07:20:23.654\"}"
GET receive {"name": "lucy", "starttime": "2022-11-14 07:20:23.654"}
2 subprocess模块详解
subprocess是Python与系统交互的一个库,该模块允许生成新进程,连接到它们的输入/输出/错误管道,并获取它们的返回代码。
该模块旨在替换几个较旧的模块和功能:
os.system
os.spawn
os.popen
popen2
commands
运行python的时候,我们都是在创建并运行一个进程。
linux中一个进程可以fork一个子进程,并让这个子进程exec另外一个程序。
在python中,我们通过标准库中的subprocess包来fork一个子进程,并且运行一个外部的程序。
subprocess包中定义有数个创建子进程的函数,这些函数分别以不同的方式创建子进程,我们可以根据需要来从中选取一个使用。
subprocess还提供了一些管理标准流(standard stream)和管道(pipe)的工具,从而在进程间使用文本通信。
使用subprocess启动电脑的子进程。
subprocess模块,允许你生成新的进程,连接它们的输入、输出、错误管道,并且获取它们的返回码。
2.1 旧有模块的使用
2.1.1 os.system()
执行操作系统的命令,将结果输出到屏幕,只返回命令执行状态(0:成功,非 0 :失败)。
import os
re = os.system("ls")
print("下面的是返回的内容")
print(type(re))
print(re)
结果自动输出到屏幕。0表示执行成功。
2.1.2 os.popen()
执行操作系统的命令,会将结果保存在内存当中,可以用read()方法读取出来。
import os
re = os.popen("ls")
print("下面的是返回的内容")
print(type(re))
print(re)
print(re.read())
结果保存在内存当中。
当需要得到外部程序的输出结果时,本方法非常有用,返回一个类文件对象,调用该对象的read()或readlines()方法可以读取输出内容。
os.popen(cmd) 要得到命令的输出内容,只需再调用下read()或readlines()等 如a=os.popen(cmd).read()
文件test.py
import sys
x = sys.stdin
for line in x:
print("receive",line)
break # 执行一次后退出循环,否则会一直持续等待运行
文件main.py
import os
a = "hello"
zz = os.popen("echo {}| python test.py".format(a)).read()
print(zz)
2.2 subprocess模块
2.2.1 subprocess.run()
import subprocess
re = subprocess.run("ls -al",shell=True)
print(type(re))
print(re)
(1)python解析,则传入命令的每个参数的列表
re = subprocess.run(["ls","-al"])
(2)Linux shell解析,则传入命令字符串,并且shell=True
re = subprocess.run("ls -al",shell=True)
2.2.2 subprocess.call()
执行命令,返回命令的结果和执行状态,0或者非0。
import subprocess
re = subprocess.call("ls -l",shell=True)
print(type(re))
print(re)
0表示执行成功。
2.2.3 subprocess.check_call()
执行命令,返回结果和状态,正常为0 ,执行错误则抛出异常。
import subprocess
re = subprocess.check_call("ls -l",shell=True)
print(type(re))
print(re)
2.2.4 subprocess.getstatusoutput()
接受字符串形式的命令,返回 一个元组形式的结果,第一个元素是命令执行状态,第二个为执行结果。
import subprocess
re = subprocess.getstatusoutput("pwd")
print(type(re))
print(re)
2.2.5 subprocess.getoutput()
接受字符串形式的命令,查看执行结果。
import subprocess
re = subprocess.getoutput("pwd")
print(type(re))
print(re)
2.2.6 subprocess.check_output()
执行命令,返回执行的结果,而不是打印。
import subprocess
re = subprocess.check_output("pwd")
print(type(re))
print(re)
结果以字节形式返回。
2.3 subprocess.Popen()
其实以上subprocess使用的方法,都是对subprocess.Popen的封装,下面我们就来看看这个Popen方法。
2.3.1 stdout标准输出
2.3.2 stderr标准错误
注意:上面的提到的标准输出都为啥都需要等于subprocess.PIPE,这个又是啥呢?原来这个是一个管道。
2.3.3 poll()
定时检查命令有没有执行完毕,执行完毕后返回执行结果的状态,没有执行完毕返回None。
2.3.4 wait()
等待命令执行完成,并且返回结果状态。
2.3.5 terminate()
结束进程。
2.3.6 pid
获取当前执行子shell的程序的进程号。
3 应用
stdin输入打开的文件。
communicate">Popen.communicate
3.1 交互方式一run传参到std
3.1.1 use.py
import sys
if __name__ == "__main__":
x = sys.stdin # 从标准输入获取数据
for line in x:
print("标准输入的数据",line)
break # 执行一次之后跳出循环
3.1.2 log.txt
你好
3.1.3 main.py
import subprocess
re = subprocess.run("python3 use.py",stdin = open("log.txt","rb"),shell=True)
3.2 交互方式二popen传参到std
3.2.1 aa_call.py
# -*- coding: UTF-8 -*-
import subprocess
import json
import sys
msg_dict = {
"beginTime":"2022-11-25 17:32:03.460",# 开始时间
"overTime":"2022-11-26 17:32:03.460",# 结束时间
}
msg = json.dumps(msg_dict, separators=(',', ':'),ensure_ascii=False)
child1 = subprocess.Popen("python aa_main.py",shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE)
re = child1.communicate(msg.encode("utf-8"))
re = re[0].decode("utf-8")
print("主进程",re)
zz = json.loads(re)
print(zz)
3.2.2 aa_main.py
# -*- coding: UTF-8 -*-
import sys
if __name__ == "__main__":
line = sys.stdin.readline()
print(line)
3.3 传参到sys.argv
3.3.1 test_call.py
# -*- coding: UTF-8 -*-
import sys
import subprocess
import json
msg_dict = {
"steps":[{"innerTag": "GAP_ACT","step":5},{"innerTag": "GAP_SET","step":10}],
"calMode":1,
"inscode":"ins6115",
"algcode":"b_011",
"beginTime":"2022-11-24 17:32:03.460",
"overTime":"2022-11-25 17:32:03.460",
"windowType":0,
"window":20,
"slide":10,
"triggercountset":1,
"mode_msg":[{'name': '逻辑条件1', 'value': '≥'}, {'name': '逻辑条件2', 'value': '≥'}],
"thdIn":[{'name': '数据阈值', 'thdParamKey': 'thd_param_数据阈值', 'value': '20'}, {'name': '持续超限阈值', 'thdParamKey': 'thd_param_持续超限阈值', 'value': '2'}]
}
msg = json.dumps(msg_dict, separators=(',', ':')) # 中文默认使用gbk编码
print("替换前",msg)
msg = msg.replace('"','\\"')
print("替换后",msg)
cmd_str = "python aa_use.py {}".format(msg)
print(cmd_str)
re = subprocess.getoutput(cmd_str)
print(re)
3.3.2 aa_use.py
存在空格的话,传参会被拆分成多个变量,所以用空格进行拼接。
# -*- coding: UTF-8 -*-
import sys
import json
if __name__ == '__main__':
aa = " ".join(sys.argv[1:])
aa = json.dumps(aa)
bb = json.loads(aa)
out_dict ={"接收":bb}
print(json.dumps(out_dict))
3.3.3 命令行验证方式
注意外边的引号不要去掉。
python3 aa_use.py "{\"steps\":[{\"innerTag\":\"690614M05*00*F4_WS_ROLLGAP_ACT\",\"step\":5},{\"innerTag\":\"690614M05*00*F4_WS_ROLLGAP_SET\",\"step\":10}]}"