2014-11-24 3 views
5

Я пытаюсь добавить файл в архив tar из выходного файла программы, не генерируя его на диске. Подумайте о файле VERSION, который автогенерируется при запуске скрипта сборки. Я попытался это, но разыменованные символический только именованный канал, а не обычный файл:Добавить stdin в качестве другого файла в tar-архив

$ date +%s | \ 
    tar cf test.tar \ 
    --dereference \ 
    --transform="s#/proc/self/fd/0#VERSION#" \ 
    /proc/self/fd/0 \ 
    other_files \ 
    and_folders/ 

Результат должен быть файл VERSION с меткой времени внутри архива дегтя ж/о локально генерации файла:

$ tar tf test.tar 
VERSION 
other_files 
and_folders 

ответ

1

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

Возможно, вы захотите попробовать опцию -A (или --concatenate). Это позволит вам создать файл в /tmp, добавить его в архив TAR и затем добавить остальные файлы на втором шаге. Таким образом, вы можете создавать произвольные пути для файла VERSION.

+0

Спасибо! Это в основном то, как я это делаю прямо сейчас. Выполнение 'mktemp', добавив его в архив с помощью' --transform = s/tempfile/VERSION/', а затем удалив. Я просто надеялся сделать этот шаг немного более лаконичным с какой-то магией труб. – Boldewyn

+0

Это единственный способ сделать это, потому что вы не можете дать TAR имя файла и его содержимое через каналы. '/ proc/self/fd/0' не работает, поскольку« tar »архивирует ссылки как специальные файлы, а не расширяет их содержимое. Я также удивлен, что '--dereference' не отключает это в этом случае. –

+1

Ну, '--dereference' действительно имеет эффект: без, упакованный'/proc/self/fd/0' остается символической ссылкой, с ним это именованный канал (тип, который 'ls -F' добавляет' | 'to). Но упакованная труба имеет ограниченное использование ... – Boldewyn

1

Хотя верно, что tar работает с файлами, это не значит, что вам нужно создавать временные файлы самостоятельно, и я бы советовал бы ему.

Вы можете использовать подстановку процесса для этого (Bash поддерживает это, Fish делает также в slightly different syntax).

tar cvaf a.tgz <(echo 1.0.0) file1 file2 -P --transform 's:^/.*:VERSION:' 

-P (--absolute-names) здесь, чтобы определить временный файл для преобразования имен переименовать его. Надеемся, что другие файлы являются локальными.

Если это не так, и некоторые другие файлы добавляются абсолютными путями (что, вероятно, не является общим случаем), то вы можете либо уточнить преобразование regexp, либо использовать двухэтапное решение с созданием архива, а затем (как отметил Аарон).

+0

Это связано с той же проблемой, что и с моим решением '/ proc':' tar' упаковывает трубу, а не обычный файл. При распаковке он говорит: '$ cat VERSION \ ncat: VERSION: файл или папка не найдены'. – Boldewyn

+1

@Boldewyn Это имеет тенденцию отличаться от разных оболочек. Рыба создает настоящие именованные каналы с 'mkfifo' (например,'/tmp/.psub.O02RnmHZ5g'), и предлагаемый метод работает отлично. Bash использует некоторые магические файлы, такие как '/ dev/fd/63'. К сожалению, похоже, нет встроенного способа переключения на 'mkfifo' для замещения процесса в Bash. – eush77

+0

Интересно! Хорошо, это действительно сработает, но я привязана к Башу. – Boldewyn

Смежные вопросы