tar解压时--exclude需配合--wildcards才有效,否则忽略;正确做法是先用tar -tzf列出并grep过滤,或用tar -xzf --wildcards --exclude='*.sh'等排除危险后缀,再chmod -x清理执行权限。

tar 本身在解压阶段(-x)不支持按文件后缀过滤或跳过特定类型文件。它没有内置的 --exclude 解压选项——该参数仅在打包(-c)时生效。
这意味着:你无法用 tar -xzf archive.tar.gz --exclude='*.sh' 这类命令阻止 .sh、.py、.pl 等脚本文件被解压出来。--exclude 在 -x 模式下会被忽略,甚至可能报错或静默失效。
✅ 正确做法:分两步处理(安全可靠)
1. 先列出归档内容,筛选出危险后缀文件
用 -t 查看所有成员,结合 grep -v 排除目标后缀:
tar -tzf archive.tar.gz | grep -v '\.\(sh\|py\|pl\|rb\|php\|js\|bash\|zsh\)$'
注意:正则需转义点号,
$锚定结尾,避免误匹配(如script.sh.bak不应被排除,但script.sh应排除)。
2. 只解压“白名单”文件(推荐)
用 --wildcards + --no-auto-convert(部分 GNU tar 支持),或更通用的方式是:
# 提取所有非敏感后缀文件(即排除 .sh/.py/.pl 等) tar -xzf archive.tar.gz --wildcards --exclude='*.sh' --exclude='*.py' --exclude='*.pl' --exclude='*.rb' --exclude='*.php' --exclude='*.js' --exclude='*.bash' --exclude='*.zsh'
✅ 这个 --exclude 在 -x 模式下是有效的(GNU tar ≥ 1.29,默认启用),但注意:
- 必须写在
-x后、-f前; -
--wildcards是启用通配符匹配的前提(否则*.sh当字面量处理); - 排除模式区分大小写(
.PY不会被*.py匹配,如需兼容可加--ignore-case,但非所有版本支持)。
示例完整命令:
tar -xzf archive.tar.gz --wildcards --exclude='*.sh' --exclude='*.py' --exclude='*.pl' --exclude='*.php' --exclude='*.js'
⚠️ 补充提醒:别依赖路径名过滤来防恶意脚本
- 即使排除了常见后缀,攻击者仍可能上传
payload(无扩展名)、runme、.env或伪装成图片的脚本(如logo.png.php); - 更稳妥的做法是:解压到隔离目录 + 设置
noexec挂载选项 + 使用chmod -x批量清除执行权限:
mkdir safe-unpack && cd safe-unpack
tar -xzf ../archive.tar.gz
find . -type f \( -name '*.sh' -o -name '*.py' -o -executable \) -exec chmod -x {} +
? 小结关键点
-
--exclude在tar -x中可用,但需配合--wildcards; - 不要省略
--wildcards,否则*.py不起作用; - 排除列表建议覆盖:
sh,py,pl,rb,php,js,bash,zsh,ps1,cmd,bat; - 解压后主动清理执行权限,比单纯靠后缀过滤更可靠;
- 对来自不可信源的 tar 包,优先考虑用沙箱环境解压(如容器、chroot)。











