python - tar 命令的子进程 Popen 和 shell=False 出错
问题描述
我有以下旨在缩小的简单python代码
/usr/bin/tar -czvf x002.tgz *.py
代码是:
import subprocess
base_dir = "/home/workspace/x002"
tar_file = "x002.tgz"
py_file = "*.py"
p = subprocess.Popen(["/usr/bin/tar", "-czvf", tar_file, py_file], cwd=base_dir, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
shell=False)
results = []
while True:
line = p.stdout.readline().decode('utf8').strip()
if line == '' and p.poll() is not None:
break
else:
results.append(line)
print(results)
py
确认目录下存在文件base_dir
,但是报错如下,不知道问题出在哪里,有大神帮忙看看吗?谢谢!
['tar: *.py: Cannot stat: No such file or directory', 'tar: Exiting with failure status due to previous errors', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']
解决方案
这个简单的代码将重现您面临的问题:
import subprocess
p = subprocess.Popen(
["ls", "*"],
shell=False
)
问题是通配符*
扩展是一个shell(bash
等zsh
)特性;tar
之类的命令ls
不明白。它在命令执行之前由 shell 评估(使用exec
系统调用)。您可以通过提供shell=True
. 它将导致 Python 使用 shell 来执行命令。在此处阅读更多相关信息:subprocess 中 'shell=True' 的实际含义。
但是,最好shell=False
在 Python 脚本中使用,因为这样可以避免产生额外的 shell。Python 有一个称为glob的等效功能,它可以做同样的事情。这将稍微改变编码风格,而不是考虑在 Python 的交互式 shell 中执行命令,而是考虑使用 Python 的变量、函数等特性来做同样的事情。
推荐阅读
- java - 迁移到 Spring 5.3
- ios - 呈现工作表时Swiftui删除工具栏
- python - 尝试绘制条形图时,Jupyter 笔记本一直冻结?
- sql - SQL如何连接两列添加逻辑条件
- php - 根据 WooCommerce 我的帐户中的自定义上传字段更改 WordPress 用户个人资料图片
- firebase - 您可以使用生成的访问代码在 Firebase 身份验证中登录用户吗?
- php - 将站点从本地转移到 AWS 后,Wordpress 样式和管理员无法正常工作
- c# - 输入值时如何停止错误“列用户名不能为空”
- java - 如何在 ReactJS-输出 [object Object] 中的功能组件之间传递值?
- malloc - malloc 不返回堆区域中的地址