执行Git+Tar批量复制文件命令报错:xargs: tar: terminated by signal 13
解决
xargs: tar: terminated by signal 13的方案 首先得说清楚,这个错误里的signal 13是SIGPIPE,本质是管道的一端已经关闭(比如负责解压的tar -x已经处理完所有数据),但另一端的进程(这里是xargs启动的tar -c)还在往管道里写数据,所以被系统终止了。问题根源在于xargs会把git ls-files输出的文件列表分成多个批次,逐个启动tar -c进程,而管道的读写节奏没匹配上。
下面给你几个靠谱的解决办法:
方法1:去掉xargs,让tar直接读取文件列表
git ls-files输出的null分隔文件名,tar本身就支持直接读取,不需要xargs中转。用这个命令替代原来的:
git ls-files -z | tar -c --null -T - | tar -x -C ~/tmp
这里的--null告诉tar文件名是用null分隔的,-T -表示从标准输入读取要打包的文件列表。这样整个流程只用一个tar -c进程,不会有分批次导致的管道问题,同时完美保留文件权限。
方法2:改用rsync(更简洁可靠)
rsync是专门做文件同步的工具,处理权限、文件属性的能力很强,而且命令更简单:
git ls-files -z | rsync -0 --files-from=- . ~/tmp
-0对应null分隔的文件名,--files-from=-表示从标准输入读取要同步的文件列表,.是源目录(当前仓库根目录),~/tmp是目标目录。这个命令不仅能保留权限,还能自动处理文件同步的细节,比tar管道的方式更稳定。
方法3:调整xargs参数(不推荐,但可以试试)
如果你一定要用xargs,可以加上--no-run-if-empty防止空列表时启动tar,同时让xargs尽量一次性传递所有文件(依赖系统命令行参数长度限制):
git ls-files -z | xargs -0 --no-run-if-empty tar -c | tar -x -C ~/tmp
不过这个方法如果遇到文件极多的仓库,还是会分批次执行,可能依然触发SIGPIPE错误,所以优先推荐前两种方案。
内容的提问来源于stack exchange,提问作者Antoine
相关产品推荐
相关产品推荐

