网站首页 > java教程 正文
今天我们来学习如何通过python脚本执行linux 操作系统命令,通过前面几期的学习,我们基本已经可以控制操作系统的目录和文件,切换到特定路径下,获取系统环境变量,获取用户命令行变量,跟用户进行入参交互。通过正则表达式过滤和加工我们需要的数据。
这次,我们来补遗,再次讲讲如何使用python脚本执行Linux shell脚本命令。
有同学可能要问了,我直接写shell 不就完了,为啥需要多此一举用python调用shell呢?
python 的优势在哪里?
- python 编码调试更加容易,灵活性更高,变量有一定的类型。
- python 更加适合大规模,模块化的自动化脚本编写。
因此,目前工作中,涉及自动化脚本的场景,多用python替代shell。
于是,使用python执行shell命令,就是替换中的关键功能了,实际上前面有一期已经给大家介绍了四种python执行shell脚本命令的方式。
本次,我们聚焦于subprocess 这种官方推荐的形式,并给大家及进行详细介绍。
先看一个简单的示例:
import subprocess
>>> subprocess.run(["date"])
Fri Mar 22 21:16:26 CST 2024
// 通过python执行date shell命令,结果打印
CompletedProcess(args=['date'], returncode=0)
// 返回了一个CompletedProcess对象
// 可以看到返回值returncode 为0
// 代表正确执行返回
如果我们执行的语句出现错误会发生什么呢?
>>> result = subprocess.run(["ls", "file_not_exists"])
ls: cannot access 'file_not_exists': No such file or directory
>>> print(result.returncode)
2 // 我们发现,执行ls指令,失败后返回非0值
上面的一些shell命令,包括chmod, ls, date 等,我们一般只关心这些命令调用后是否成功,我们不需要对执行结果进行进一步处理时,直接判断执行返回值的returncode是否为0就足够了。
但是如果有一些shell命令,我们执行后,需要对执行结果进行进一步过滤,处理,获取一些有用信息时,那么上面的方式就不适用了。
那应该怎么办呢?
>>> result =
subprocess.run(["host", "8.8.8.8"], stdout=subprocess.PIPE)
>>> print(result.returncode)
0
>>> print(result.stdout)
b'8.8.8.8.in-addr.arpa domain name pointer dns.google.\n'
// 我们可以使用stdout属性或者capture_out=True
// 然后通过result.stdout获取到执行结果
host可以根据入参的ip地址,进行域名获取功能。
这里有个小tips,大家知道那个stdout显示结果的字符串前面为啥有个b不?
其实这代表的是,这个字符串它不是一个python标准的字符串,而是字节数组类型。
如果想进一步获取到python标准的字符串,可以使用decode方法。
>>> ret_list = result.stdout.decode().split()
// decode 之后split,存储为列表
>>> print(ret_list)
['8.8.8.8.in-addr.arpa', 'domain', 'name', 'pointer', 'dns.google.']
// 打印结果
那么如果我们执行某个shell指令错误,如何获取错误结果呢?答案是使用stderr。
示例如下:
>>> result = subprocess
.run(["rm", "does_not_exists"],
stderr=subprocess.PIPE, stdout=subprocess.PIPE)
// 想删除一个不存在的文件
>>> print(result.returncode)
1
>>> print(result.stdout)
b''
// 执行结果为空,因为出现错误了
>>> print(result.stderr)
b"rm: cannot remove 'does_not_exists': No such file or directory\n"
// 打印错误结果在stderr中
然后我们在学会了上面的基础使用方法后,考虑一种场景。
场景示例:
- 我们想执行一个自己的二进制程序,需要把这个程序的可执行文件路径添加到操作系统的环境变量中去。
如何实现这个功能呢?
示例如下:
>>> import os
>>> import subprocess
>>> my_env_to_run_app = os.environ.copy()
>>> my_env_to_run_app
= os.pathsep.join(["/opt/myapp/",
my_env_to_run_app["PATH"]])
>>> result = subprocess.run(["myapp"], env = my_env_to_run_app)
我们通过os.environ.copy做环境变量的拷贝,然后添加自己的环境变量进去,然后在subprocess执行时,指定环境变量即可。
需要注意的是,subprocess 默认是启动了一个子线程去执行shell命令的,从上面的copy环境变量也可以看出,如果想执行一些命令直接作用在当前shell 中,则必须指定shell。
我们证明一下这件事情:
result = subprocess.run(["export", "Fruit=Apple"], shell=True)
// 导出一个环境变量Fruit
>>> print(result.returncode)
0 // 执行成功
>>> print(os.environ["LOGNAME"])
chen // 正常系统环境变量
>>> print(os.environ["Fruit"])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.6/os.py", line 669, in __getitem__
raise KeyError(key) from None
KeyError: 'Fruit'
// 发现通过subprocess export
// 的变量不在当前shell中,无法获取到
好的,今天就先讲到这里,你的关注就是我分享的动力,希望大家关注并给我留言,任何想听的想看的,都可以留言告诉我,给大家分享。
猜你喜欢
- 2024-12-25 Python exe 文件反编译为 Python 脚本
- 2024-12-25 Python实用脚本技术及示例 python脚本例子
- 2024-12-25 Python:11个比较好用的自带脚本工具
- 2024-12-25 python脚本控制安卓手机,可以用来做什么你知道吗?
- 2024-12-25 Python番外篇之代码编译与字节码 python如何生成字节码文件
- 2024-12-25 一段获取Linux系统信息的python脚本
- 2024-12-25 在 Java 代码中来一段 JavaScript?聊聊 Flowable 中的脚本任务
- 2024-12-25 小白必备:如何用auto-py-to-exe轻松打包 Python 脚本
- 2024-12-25 三十个常见的python脚本,别再弄错,会吃亏的,附视频教程
- 2024-12-25 python生成脚本与部署的方案 python生成脚本与部署的方案怎么写
你 发表评论:
欢迎- 04-27微服务部署架构设计详解(图文全面总结)
- 04-27Java微服务架构选型与对比:一场技术流派的巅峰对决
- 04-27微服务架构下Java的最佳实践
- 04-27Java微服务架构选型:优雅拆分与高效整合
- 04-27微服务架构下的Java代码拆分策略:像拼图一样构建系统
- 04-27微服务架构下的Java最佳实践
- 04-27微服务架构下Java的挑战与机遇
- 04-27微服务架构下Java事务管理的艺术
- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)