【问题标题】:xargs: tar: terminated by signal 13xargs: tar: 由信号 13 终止
【发布时间】:2019-09-18 06:30:51
【问题描述】:

我正在运行以下命令以使用tar 将文件从git 给出的列表复制到另一个目录以保留权限。

git ls-files -z | xargs -0 tar -c | tar -x -C ~/tmp

这似乎适用于某些存储库,但不适用于我的:

xargs: tar: terminated by signal 13

【问题讨论】:

    标签: pipe tar xargs


    【解决方案1】:

    回答我自己的问题1

    信号 13 管道损坏:接收端停止读取,但我们仍在管道中。

    我的第一个提示是一个有问题的文件,所以让我们将 -t 选项添加到 xargs 以便它打印命令:

    git ls-files -z | xargs -t -0 tar -c | tar -x -C ~/tmp
    

    输出:

    tar -c [long list of files (2994 files)]
    tar -c [sightly less long list of files (~700 files)]
    

    此时问题很明显:我们将 两个 tar 调用合并为一个,因此管道已损坏(信号 13)。

    确实,阅读xargs手册,我们可以读到:

    command 的命令行一直建立到达到系统定义的限制(除非使用了 -n 和 -L 选项)。 将根据需要多次调用指定的命令以用完输入项列表。

    您可以使用xargs --show-limits 查看xargs 的限制。如果参数长度超过系统限制,xargs 会生成多个命令。

    由于命令行的系统限制很高(至少在我的系统上,它是 131072 字节,我的文件相当于 ~3000 个文件),这可以定义为一般情况。这意味着如果文件列表符合系统定义的限制,则初始命令运行良好。

    我们可以通过xargs 使用-L 选项在每次调用中抛出的文件数量限制每个案例(至少有2 个文件):

    git ls-files -z | xargs -L 1 -t -0 tar -c | tar -x -C ~/tmp
    

    解决方案实际上是完全删除xargs,通过使用tar 的-T 选项,从文件中读取文件列表(或-,意思是stdin):

    git ls-files -z | tar --null -T - -c | tar -x -C ~/tmp
    

    git ls-files | tar -T - -c | tar -x -C ~/tmp
    

    1https://discuss.circleci.com/t/local-checkout-fails-using-cli-tar-terminates-with-signal-13/28632/14

    【讨论】:

    • 这是一篇很棒的文章。不要忘记将您的答案标记为解决方案:)
    • 如果你能提到在哪里可以找到或更改系统限制,那就太好了,man xargs 列出了几个不同的值,不确定哪个是在这里玩的。
    • 是的,好点。它实际上不是文件的限制,而是最大命令长度的限制。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-11
    • 1970-01-01
    • 2017-06-23
    相关资源
    最近更新 更多