xargs: tar: завершается сигналом 13 - PullRequest
2 голосов
/ 29 апреля 2019

Я запускаю следующую команду, чтобы скопировать файлы из списка, заданного git, в другой каталог, используя tar для сохранения прав.

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

Это похоже на некоторые репозитории, но не по моему:

xargs: tar: terminated by signal 13

1 Ответ

2 голосов
/ 29 апреля 2019

Отвечая на мой вопрос 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, мы можем прочитать, что:

Командная строка для команды создается до тех пор, пока она не достигнет системного предела (если не используются опции -n и -L). Указанная команда будет вызываться столько раз, сколько необходимо для использования списка элементов ввода.

Вы можете проверить пределы xargs с помощью xargs --show-limits. 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

...