Bash脚本中zip命令排除参数失效问题求解
解决Zip命令通过字符串变量传递排除参数失效的问题
问题场景
待压缩目录结构:
dir2zip subdir1 file1.txt subdir2 file2.txt subdir3 file3.txt
直接在终端执行以下命令,能正确排除subdir3:
zip -r dir2zip.zip dir2zip -x "dir2zip/subdir3/*"
执行输出:
manfred@altair:~/data$ zip -r dir2zip.zip dir2zip -x "dir2zip/subdir3/*" adding: dir2zip/ (stored 0%) adding: dir2zip/subdir2/ (stored 0%) adding: dir2zip/subdir2/file2.txt (deflated 72%) adding: dir2zip/subdir1/ (stored 0%) adding: dir2zip/subdir1/file1.txt (deflated 68%)
但将参数存为字符串变量后执行,排除规则失效,subdir3被一同压缩:
zipvar="-r dir2zip.zip dir2zip -x \"dir2zip/subdir3/*\"" echo $zipvar # 输出:-r dir2zip.zip dir2zip -x "dir2zip/subdir3/*"
执行zip $zipvar的输出:
manfred@altair:~/data$ zip $zipvar adding: dir2zip/ (stored 0%) adding: dir2zip/subdir3/ (stored 0%) adding: dir2zip/subdir3/file3.txt (deflated 94%) adding: dir2zip/subdir2/ (stored 0%) adding: dir2zip/subdir2/file2.txt (deflated 72%) adding: dir2zip/subdir1/ (stored 0%) adding: dir2zip/subdir1/file1.txt (deflated 68%)
解决办法
1. 使用数组存储参数(推荐)
在bash中用数组保存命令参数,能完美处理带通配符、空格的参数,避免分词错误:
# 定义参数数组,每个元素对应一个命令参数 zip_args=( -r dir2zip.zip dir2zip -x "dir2zip/subdir3/*" ) # 执行zip命令,展开数组时用双引号包裹,确保每个参数被正确传递 zip "${zip_args[@]}"
执行后subdir3会被正确排除。
2. 使用eval(不推荐,有安全风险)
如果必须用字符串变量传递,可以借助eval解析参数,但要注意:如果参数包含不可信内容,可能会执行恶意命令,存在安全隐患:
zipvar="-r dir2zip.zip dir2zip -x \"dir2zip/subdir3/*\"" eval zip $zipvar
失效原因
直接执行zip $zipvar时,bash会对字符串做分词处理,把带引号的"dir2zip/subdir3/*"当作一个带引号的完整参数传递给zip,而zip会尝试匹配路径中包含引号的"dir2zip/subdir3/*",自然找不到对应目录,导致排除规则失效。
用数组存储时,每个元素会被当作独立的参数,引号被正确解析,zip能拿到真正的排除路径dir2zip/subdir3/*,从而生效。
内容的提问来源于stack exchange,提问作者schweigerson
相关产品推荐
相关产品推荐

