「人生苦短我用Python」之Python运行外部shell命令

有时候我们写 Python 可能遇到调用 shell 命令行里的命令获取一些信息,也就是要在 Python 脚本代码里运行 shell 命令。

subprocess 模块

使用 Python 里的 subprocess 模块来运行 shell 命令。这个模块可以可以看文档:执行外部命令并获取它的输出

import subprocess

# shell 命令获得系统时间
command = 'date'

#subprocess.Popen 运行 command
command_stdout = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()

# 输出结果是bytes 类型
print('转换前', command_stdout)

# 将 bytes 类型转换 string 类型 encoding = 'utf-8'
command_stdout = str(command_stdout[0], 'utf8')
print('转换后', command_stdout)

结果如图[center]
201907
如果 shell 命令里有双引号单引号字符比如echo "Hello world"如果用上面的方式会出错, subprocess.Popen添加 shell=True 引用 shell就可以。

command = 'echo "Hello World"'
command_stdout = subprocess.Popen(command, stdout=subprocess.PIPE, 
stderr=subprocess.PIPE, 
shell=True).communicate()

command_stdout = str(command_stdout[0], 'utf8')
print(command_stdout)

201907

不过更推荐用列表的形式传递命令
command = ['echo', 'Hello World']
再比如shell命令
ffmpeg -i "concat:1.ts|2.ts" -vcodec copy -acodec copy temp.mp4
写成 List形式
command = ["ffmpeg", "-i", "concat:1.ts|2.ts", "-vcodec", "copy", "-acodec", "copy", "temp.mp4"]

command = ['echo', 'Hello World']
# command = ["ffmpeg", "-i", "concat:1.ts|2.ts", "-vcodec", "copy", "-acodec", "copy", "temp.mp4"]

command_stdout = subprocess.Popen(command, stdout=subprocess.PIPE, 
stderr=subprocess.PIPE, ).communicate()

command_stdout = str(command_stdout[0], 'utf8')
print(command_stdout)

201907
这更准确地表示将要传递到结束进程的准确的参数集,并且消除了对shell引用的需要。也就是说,如果你绝对要使用纯字符串版本,只需使用不同的引号(和shell = True)

用 invoke 模块 run

也可以用第三方库 invoke 里面的 run 运行 shell 命令。了解invoke是在使用 Fabric 库完成自动化操作知道的。比如使用 Fabric 连接到远程服务器然后执行一些 shell 命令运行脚本等。

Invoke is a Python (2.7 and 3.4+) task execution tool & library, drawing inspiration from various sources to arrive at a powerful & clean feature set.

#!/Users/northgod/.pyenv/shims/python3
# -*- coding:utf-8 -*-
from invoke import run

command = 'echo "结果第一行\n我是第二行\n第三行在这"'

# 如果使用 hide=True 将运行的过程隐藏,
# 结果 stdout.splitlines()以每行为一个元素 列表形式保存
# 不使用 hide=True 结果会实时显示在命令行
cmd_stdout = run(command, hide=True, warn=True)

cmd_stdout = cmd_stdout.stdout.splitlines()

print(cmd_stdout)
print(cmd_stdout[0])

invoke-run

invoke-run

更多以及其他功能请参考 Welcome invoke

你也可能喜欢

发表评论

您的电子邮件地址不会被公开。 必填项已用 * 标注

提示:点击验证后方可评论!

插入图片

标签云

「人生苦短我用Python」之Python运行外部shell命令

长按储存图像,分享给朋友

微信扫一扫

微信扫一扫