Как заставить tar работать с опцией 'change directory'

8

У меня есть следующая структура каталогов:

base/
   files/
   archives/
   scripts/

Я хочу, чтобы скрипт запускался scripts/, сжимал файлы, которые совпадают, results.*.logв files/архив tar с gzip archives/.

Я пытаюсь следующую команду:

tar czfC ../archives/archive.tar.gz ../files results.*.log

Но я получаю

tar: results.*.log: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors

Пока

tar czfC ../archives/archive.tar.gz ../files results.a.log

работает как положено. Также

tar czf ../archives/archive.tar.gz ../files/results.*.log

работает так, как мне хотелось бы, за исключением того, что он добавляет префикс files/к файлу, а также выдает предупреждение:

tar: Removing leading `../' from member names

Таким образом, мой вывод заключается в том, что tarпри использовании этой -Cопции глобирование не работает должным образом . Любой совет о том, как мне сделать эту работу простым способом?

Юваль
источник

Ответы:

3

Напишите это более переносимым способом:

(cd ../files && tar cf - results.*.log) | 
  gzip -9 > ../archives/archive.tar.gz
Стефан Шазелас
источник
Глоб будет по-прежнему интерпретироваться в текущем каталоге, прежде чем cdпроизойдет.
vonbrand
1
@ vonbrand, нет, конечно, не будет. &&Это как ;или новая строка, он разделяет две команды. Это все равно что сказать, что после запуска cdлюбой глобал раскроет файлы в предыдущем каталоге.
Стефан Шазелас
Вы правы. Никто не заканчивает учиться.
vonbrand
5

Здесь нет «разбрасывания гудрона», разбрасывание производится оболочкой. И оболочка понятия не имеет, что tar -C somedirбудет делать свою работу somedir, любые глобусы раскрываются в текущем каталоге.

vonbrand
источник
Действительно, если results.a.logсуществует в каталоге, из которого запускается скрипт, он работает. Но я не понимаю, почему это происходит, так как -Cобозначает изменение каталога, поэтому текущий каталог должен быть тот, с которым results.a.log. Я не могу принять ваш ответ, потому что вы не предлагаете решение.
Юваль
2
Оболочка принимает команду, расширяет глобусы в текущем каталоге, создает аргументы из вышеперечисленного и запускает tarпрограмму, которая значительно позже меняет каталог. Не могу "решить" вашу проблему, извините. Единственный выход - перейти в каталог, в котором вы хотите выполнить глобализацию, или выполнить глобализацию в каталоге и сохранить результаты в файле или переменной.
vonbrand
1

Вы можете разрешить findвыполнять глобализацию и опустить опцию «изменить каталог» tar, удалив files/префикс перед созданием tar-файла.

--no-recursionВариант не tarявляется обязательным , так как никаких каталогов не будут заархивированы.

cd base/scripts

# gnutar
# printf '%s\000' ../files/results.*.log |  # find alternative
find ../files -maxdepth 1 -type f -name "results.*.log" -print0 | 
   gnutar --transform="s|^\.\{0,1\}\.\{0,1\}/\{0,1\}files/||" -cf - --null --no-recursion -T - | 
   gzip -9 > ../archives/archive.tar.gz
gnutar -tf ../archives/archive.tar.gz | nl
gnutar -xzf ../archives/archive.tar.gz

# bsdtar
find ../files -maxdepth 1 -type f -name "results.*.log" -print0 | 
   bsdtar -s "|^\.\{0,1\}\.\{0,1\}/\{0,1\}files/||" -cf - --null --no-recursion -T - | 
   gzip -9 > ../archives/archive.tar.gz
bsdtar -tf ../archives/archive.tar.gz | nl
bsdtar -xzf ../archives/archive.tar.gz
phron
источник
0

Я наконец-то использовал

tar czfC ../archives/archive.tar.gz ../files `find ../files/results.*.log -printf "%f\n"`
Юваль
источник
Хотя это может сработать для вас, это довольно сложный способ сделать это. Кроме того, он не будет работать с именами файлов, содержащими специальные символы, такие как пробелы. Используйте один из здравомыслящих методов, которые были предложены в ответах.
Жиль "ТАК - перестань быть злым"
0

Для этого нужно написать что-то вроде следующего:

#!/bin/sh

cd ../files
tar zcf ../archives/archive.tar.gz results.*.log
cd ../scripts
vonbrand
источник
0

Это не смола, которая делает сгусток, это оболочка. Сначала вы говорите оболочке делать globbing, а затем говорите tar об изменении каталогов. Поскольку tar получает список имен файлов относительно исходных каталогов, это не работает.

На сегодняшний день самое простое решение - позволить оболочке изменить каталог. Интерактивное:

cd ../files
tar czf ../archives/archive.tar.gz  results.*.log
cd -

В скрипте:

(
  cd ../files &&
    tar czf ../archives/archive.tar.gz  results.*.log
)

или

(
  cd ../files &&
    tar czf -  results.*.log
) >../archives/archive.tar.gz
Жиль "ТАК - перестань быть злым"
источник