Страница 1 из 1

Архивация tar-ом через stdin

Добавлено: 2009-10-26 17:53:55
Dmitriy_K
Есть задача: Во FreeBSD производится вывод некоего файла в stdin. Хотелось бы по конвейеру сжать его в tar.
Начало цепочки значения не имеет, поэтому можно условно использовать для моделирования процесса "cat txt.log |".
Не могу найти способа передать этот stdin напрямую в tar (у меня он воспринимает на входе только имена файлов). Это, вообще, возможно или только можно использовать gzip/bzip2 ?
Есть, конечно альтернатива: использовать pipe. Но он, насколько понимаю, пишется на диск, что неоправданно затратно. Может, я чего не понял и есть экономный по ресурсам/операциям способ?
Кстати, столкнулся с непонятной фигнёй - не проходит команда типа:

Код: Выделить всё

mkfifo tar_pipe && cat txt.log > tar_pipe
Можно только последовательно:

Код: Выделить всё

mkfifo tar_pipe
cat txt.log > tar_pipe
Интересно, из-за чего так?

Re: Архивация tar-ом через stdin

Добавлено: 2009-10-26 18:07:08
zg
Dmitriy_K писал(а):Не могу найти способа передать этот stdin напрямую в tar
ну какбэ тар хранит файловую структуру, поэтому зачем на него передавать поток, если он всё равно не делает сжатие?

Re: Архивация tar-ом через stdin

Добавлено: 2009-10-26 23:54:09
Гость
как ты по pipe'у будешь передавать имя файла? Можно, конечно, повесить в цикл автоматическое добавленя файлов из pipe'а, но тогда придется отправлять файлы внутри tar-архивов. Напр.

Код: Выделить всё

# открываем pipe
$ mkfifo tar_pipe
$ while tar -rf foo.tar @- <tar_pipe; do done &

Код: Выделить всё

# шлем файл и папку в pipe
$ tar cf tar_pipe bar blah_dir/
$ tar cf tar_pipe baz

# сомтрим содержимое foo.tar'а
$ tar tf foo.tar
bar
baz
blah/a
blah/b

Re: Архивация tar-ом через stdin

Добавлено: 2009-10-27 22:18:56
Dmitriy_K
Большое спасибо за расширение горизонта моих познаний (увеличивающее количество ещё непонятого)! :roll:
Я, вообще, заинтересовался этим в плане доработки проекта чужого срипта, где планировалость перенаправлять вывод дампа MySQL напрямую в tar.

Код: Выделить всё

mysqldump --user=*** --password=*** --flush-logs $db | tar cyf > ${db}-`date "+(%d-%m-%Y)"`.sql.tbz
Вот здесь и возник затык. Ну ладно, спасибо, разобрался. Буду использовать просто bzip2:

Код: Выделить всё

mysqldump --user=*** --password=*** --flush-logs $db | bzip2 > ${db}-`date "+(%d-%m-%Y)"`.sql.bz2
Но просьба помочь до конца разобраться с "pipe".
Я попробовал поэкспериментировать на эту тему. Сделал такой скриптик:

Код: Выделить всё

#!/bin/sh
mkfifo ~/tar_pipe   #Я проставил везде использование родительского каталога в путях для универсальности.
while tar -rf ~/foo.tar @- < ~/tar_pipe; do done &
#Как вариант, чтобы не печатать имена файлов в директории вручную, используем их передачу в tar через stdin.
cd /var/mysql_backups
ls | tar cf ~/tar_pipe -T -
rm ~/tar_pipe
exit 0
Как сделать правильное завершение этого скрипта? У меня в процессах остаются два висяка: /bin/sh ./test.sh
Вообще, как-то не получается сделать по описанию использования "pipe", например, на Википедии:
http://ru.wikipedia.org/wiki/%D0%98%D0% ... 0%B0%D0%BB
Не работает:

Код: Выделить всё

mkfifo arch_pipe
gzip -c < arch_pipe > arch.gz
cat txt.log > arch_pipe
Похоже, "pipe" должен быть всегда в фоне.
И ещё вопросик, насколько "pipe" оправдан по ресурсоёмкости? Стоит ли с ним связываться, или поискать другие варианты?