Python脚本拼接日期变量后执行tar压缩命令报错问题
故障原因
- 核心问题是调用
os.popen()读取date命令输出时,返回结果末尾自带shell命令输出的换行符\n,拼接shell命令时这个换行符会把完整的tar指令截断成两部分:- 截断后的第一部分tar命令没有传入待打包的文件路径参数,触发
Cowardly refusing to create an empty archive报错 - 截断后的第二部分残次指令会尝试在当前用户无写入权限的路径查找、执行
.tar.xz相关指令,触发Permission denied报错
- 截断后的第一部分tar命令没有传入待打包的文件路径参数,触发
- 次要隐患是你定义的镜像路径
var/lib/libvirt/images/centos.qcow2是相对路径,正常情况下系统镜像存放在根目录下的绝对路径/var/lib/libvirt/images/,相对路径写法很容易因为脚本执行目录变化找不到文件。
修复方案
- 读取date命令输出后,调用
.strip()方法去掉首尾的空白字符(包括换行、首尾空格) - 拼接压缩包文件名时注意参数间隔,避免文件名和参数连写导致识别异常
- 建议把镜像路径改成绝对路径,避免路径找不到的问题
- 更稳妥的写法是直接用Python内置模块获取日期、用
subprocess模块传参执行命令,不需要手动拼接shell字符串,从根源避免shell注入、特殊字符截断命令的问题
修复后可运行代码
最小改动版本(保留原有os.system逻辑)
import os # 1. 定义虚拟机名称 vm = 'centos' # 2. 定义镜像绝对路径 path = '/var/lib/libvirt/images/centos.qcow2' # 3. 读取日期并去掉末尾换行 with os.popen('date +"%Y%m%d"') as f: vmdate = f.read().strip() # 4. 拼接压缩包文件名 archive_name = f"{vm}{vmdate}.tar.xz" # 5. 执行打包命令 os.system(f'tar cvJf {archive_name} {vm}.xml {path}')
更稳定的推荐版本
不需要调用外部shell命令取日期,也不存在命令截断风险:
import subprocess from datetime import datetime # 直接用Python内置模块取日期,无额外命令调用开销 vmdate = datetime.now().strftime("%Y%m%d") vm = 'centos' path = '/var/lib/libvirt/images/centos.qcow2' archive_name = f"{vm}{vmdate}.tar.xz" # 用列表传参,不需要手动拼接shell命令 subprocess.run(["tar", "cvJf", archive_name, f"{vm}.xml", path], check=True)
内容的提问来源于stack exchange,提问作者Aku
相关产品推荐
相关产品推荐

