3

Я нашел некоторые проблемы с Linux GNU Tar. где я использую опцию

-T -  (for file list from stdin) or
-T named_pipe_file    ,

это не работает на лету. например, простой интерактивный скрипт:

while read x; do echo $x; done|\
tar cvf tar.tar -T -

tar начинает архивирование, только когда я нажимаю ^ D для пометки ввода EOF, такая же ситуация, когда я использую именованный канал:

mkfifo named_pipe
tar cvf tar.tar -T named_pipe
while read x; do echo $x; done >named_pipe

Кажется, смола делает некоторую буферизацию. Но как долго это? Я должен перепаковать много файлов в TAR, но мало места на диске. Тогда я должен сделать это на лету. Для этого я использую опцию tar --remove-files. Но без интерактивности для опции -T это невозможно. В плане часть кода while должна распаковывать файл в файл последовательно, ожидая удаления TAR и следующего файла. Спасибо за идеи :)

моя версия tar: tar (GNU tar) 1.26 (C) 2011 FSF

3 ответа3

3

tar может добавлять к уже существующим архивам, так что вы можете сделать:

touch tarfile.tar
command_that_produces_file_list | xargs tar rf tarfile.tar

К сожалению, это не работает со сжатием на лету. К счастью, формат tar достаточно прост, мы можем взломать:

command_that_produces_file_list | {
  xargs -i sh -c 'tar c {} | head -c $(( (`stat --printf="%s" {}` + 511) / 512 * 512 + 512))';
  dd if=/dev/zero bs=512 count=2 2>/dev/null;
} | compression_utility

Вывод tar состоит из 512-байтового заголовка для каждого файла, за которым следуют достаточные 512-байтовые блоки для хранения данных файла. Затем он добавляет не менее 2 512-байтовых блоков нулей. Этот код захватывает выходные данные tar и удаляет лишние блоки нулей, объединяет выходные данные нескольких вызовов tar вместе, а затем привязывает конечные блоки нулей. Выходные данные отправляются по конвейеру в утилиту сжатия, которая работает одновременно с tar файлами.

2

Хорошие новости. Я получаю ответ на мой отчет об ошибке на bug-tar@gnu.org, цитируя:

От: Сергей Позняков дата:
Четверг, 05 сентября 2013 г. 08:40:40 +0300 subject: Re: [Bug-tar] GNU tar, опция -T из stdin или именованного канала не является интерактивной

Привет Гжегож,

Это было исправлено в git HEAD (начиная с коммита 1fe0c83d).

С уважением, Сергей

Тогда я жду, когда это будет исправлено в дистрибутивах Linux :)

0

Прочитайте это объяснение (первый ответ): В каком порядке выполняются команды по каналам?

То, что вы видите, является блокировкой tar для завершения списка ввода до того, как он начнет обработку. Возможно, выполнение обработки параллельно с вводом может быть полезным по одному, но я не думаю, что GNU Tar поддерживает это.

Я могу только догадываться, что ожидание всего списка сделано, чтобы избежать сложности во "внутренних процедурах" обработки аргументов командной строки, таких как, как обращаться с «--append и --remove-files». Я думаю, что большинство людей предпочли бы удалить все файлы навалом после того, как архив сделан, а не на лету, как желательно в этом случае.

Люди из GNU обычно очень дружелюбны, вы можете спросить, почему это не особенность, как вы можете сделать это с помощью других инструментов и даже попросить, чтобы это было частью Tar в будущем;

https://lists.gnu.org/mailman/listinfo/help-tar

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .