pipe - xargs: tar: 由信号 13 终止

标签 pipe tar xargs

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

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

这似乎适用于某些 repo 协议(protocol),但不适用于我的:

xargs: tar: terminated by signal 13

最佳答案

回答我自己的问题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手册,我们可以读到:

The command line for command is built up until it reaches a system-defined limit (unless the -n and -L options are used). The specified command will be invoked as many times as necessary to use up the list of input items.

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

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

我们可以重现每种情况(嗯,至少有 2 个文件),通过限制 xargs 将在每次调用时使用 -L 选项抛出的文件数量:

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

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

关于pipe - xargs: tar: 由信号 13 终止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55906636/

相关文章:

python - 使用 Python 子进程执行 tar 命令在给定 --exclude 选项时不会排除某些文件

Java、文件、Linux 和西里尔文

macos - 无法通过 macOS 中的 ansible unarchive 模块提取 tar 文件?

linux - 运行命令并显示控制台输出的 Bash 脚本,直到出现某些短语或超时

python - Python 中的 All-to-All 线程通信

创建我自己的重定向和重复管道函数

c - 通过函数创建管道

regex - 如何从包含文件名一部分的列表中 -find -exec cp 文件

linux - 为什么并行模式下的 xargs 不能与 grep 一起使用?

linux - 使用 find 和 xargs 列出从包含字符串中找到的文件的时间戳