最初的警告:tar不是标准定义的工具(POSIX归档程序pax),因此它的行为可以在平台之间变化,而没有任何最小的保证基线.你的旅费可能会改变.
由于这是标记的bash,您可以使用<()- 进程替换 - 生成一个文件名,在读取时,它将发出子进程的输出,而不需要临时文件.(/dev/fd如果您的操作系统支持,则通常将其实现为名称,否则将实现为命名管道).
如果你只想要cd应用tar命令,你可以按如下方式执行,将它放在子shell中并使用exec子shell将tar命令替换为自己,避免了子shell以其他方式创建的fork惩罚:
dir=/Library/WebServer/a/a/e/j
(cd "$dir" && exec tar --null -zcvf j.tar.gz -T <(printf '%s\0' *.json) )
Run Code Online (Sandbox Code Playgroud)
或者,如果您tar支持它,您可以使用--include告诉tar自己过滤名称:
tar -C "$dir" --include='*.json' -cvzf "$dir/j.tar.gz" .
Run Code Online (Sandbox Code Playgroud)
注意事项:
printf '%s\n' *.json是免于这个因为printf是内置的壳; 因此,glob结果不会放入execv-family系统调用的参数中,因此ARG_MAX不适用.--nullon find和'%s\0'on printf(或者-print0如果您生成名称列表find)可以防止带有文字换行符的恶意生成的名称无法将任意名称注入流中.想想如果有人跑了会发生什么mkdir -p $'hello/\n/etc/passwd\n.json'- 你不想/etc/passwd进入你的tarball.