作为一个Python开发者,啥时候都离不开Linux命令,写代码写着写着就想执行个ls看看文件,或者来个grep搜索一下内容。要是每次都要切换到终端,那也太麻烦了。Python早就想到这一点了,给我们提供了几种在代码中执行shell命令的方式。
os.system - 简单粗暴有隐患
最基础的方式就是用os.system,代码超级简单:
import os
exit_code = os.system('ls -l')
print(f'命令执行完成,退出码: {exit_code}')
不过这个方法可有点简陋,就像用榔头砸核桃 - 能用,但不够优雅。它只能返回命令的退出码,想要获取命令的输出内容?没门!
subprocess - 新时代的shell执行利器
看看现在主流的做法,用subprocess模块:
import subprocess
# 执行单个命令
result = subprocess.run(['ls', '-l'], capture_output=True, text=True)
print(result.stdout) # 输出命令结果
# 执行带管道的命令
ps_output = subprocess.run('ps aux | grep python',
shell=True,
capture_output=True,
text=True)
print(ps_output.stdout)
温馨提示:用subprocess.run的时候记得加上capture_output=True和text=True,不然拿到的结果是二进制的,打印出来就是一串乱码,够闹心的。
异常处理 - 优雅地处理命令执行失败
命令执行可不是百发百中的,万一命令不存在或者执行失败了咋办?
try:
result = subprocess.run(['some_invalid_command'],
capture_output=True,
text=True,
check=True) # 加上check=True会在命令失败时抛出异常
except subprocess.CalledProcessError as e:
print(f'哎呀,命令执行出错啦:{e}')
print(f'错误输出:{e.stderr}')
环境变量和工作目录
有时候执行命令还需要设置一些环境变量,或者在特定目录下执行:
# 设置环境变量
my_env = os.environ.copy() # 复制当前环境变量
my_env['PATH'] = '/usr/local/bin:' + my_env['PATH'] # 修改PATH
# 在指定目录下执行命令
result = subprocess.run(['ls', '-l'],
env=my_env,
cwd='/tmp', # 在/tmp目录下执行
capture_output=True,
text=True)
实时获取命令输出
要是命令执行时间比较长,想实时看到输出咋办?用Popen就行:
process = subprocess.Popen(['ping', 'google.com'],
stdout=subprocess.PIPE,
universal_newlines=True)
while True:
output = process.stdout.readline()
if output == '' and process.poll() is not None:
break
if output:
print(output.strip())
小技巧 :在处理大量输出的时候,最好用readline()一行一行地读,这样不会把内存撑爆。
到这儿你已经掌握了在Python中执行shell命令的精髓。记住一点, 能用Python内置功能实现的,就别用shell命令 ,毕竟Python的跨平台性更好,代码也更容易维护。不过有些时候,shell命令确实是最便捷的选择,这时候就放心大胆地用起来吧!
领取专属 10元无门槛券
私享最新 技术干货