Команда tar в цикле for

Как вы уже поняли, создание лупа состоит из двух шагов:

  1. Настройка устройства лупа
  2. Его монтирование

Конечно, я мог бы просто сделать chown myuser /dev/loop*, но похоже, что это может стать серьезной проблемой безопасности.

Я полагаю, что это позволит создать соответствующее петлевое устройство (предоставив доступ к /dev/loopcontrol). Я не знаю, есть ли какое-то доступное пространство имен, которое влияет на представление петлевых устройств. Это, по-видимому, позволит сделать это более безопасно.

Шаг 2 по-прежнему не выполняется: пространства имен пользователей позволяют создавать новые пространства имен монтирования, в которых пользователи могут создавать новые монтирования, но это довольно ограничено — CAP_SYS_ADMIN в исходном пространстве имен. по-прежнему требуется для монтирования блочных устройств: как говорит user_namespaces(7)

Однако обратите внимание, что монтирование блочных файловых систем может выполняться только процессом, который содержит CAP_SYS_ADMIN в начальном пользователе. пространство имен.

Loop-устройства — это блочные устройства, поддерживаемые файлами, так что это по-прежнему запрещено. Это прискорбно, я думаю, должен быть способ, чтобы это работало безопасно. Но я предполагаю, что в нем много сложностей (особенно с setuid), по которым он еще не реализован.

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

0
06.08.2016, 08:52
3 ответа

Каждый раз, когда цикл выполняется, выполняется команда tar , чтобы поместить один файл в файл server2.tar.gz . Файл будет иметь только один файл.

Для добавления файлов используйте опцию tar:

tar --append -zcvf server2.tar.gz "$i"

или просто передайте список файлов tar (пожалуйста, не используйте эту команду):

tar -zcvf server2.tar.gz  $(ls -l|awk '/'$Previousmonth'/&&/server.log./{print $NF}')

Однако в этой командной строке есть некоторые проблемы:

  • parsing ls вывод (неверный).
  • с использованием $ Предыдущий месяц без кавычек (неверно).
  • создание списка файлов, в которых могут быть встроенные пробелы (ненадежный).

используйте эту (пару) команд вместо:

month=$(date "+%Y-%m-" --date '1 month ago')
find ./ -name "server.log.${month}*" -exec tar -zcvf server2.tar.gz '{}' \+
3
28.01.2020, 02:14

@ John1024 уже дал вам хороший ответ , но я подумал, что добавлю еще немного.

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

Если ваш архив называется /data/logs/logfiles-2016-08.tar для августа, а сами ротационные файлы журналов на определенную дату называются / var / log / servicename-2016-08-06.log (для ряда различных значений servicename ) у вас может быть небольшой сценарий, который задание cron вызывает в 3 часа ночи, которое выполняет

#!/bin/sh

yyyymm="$( date --date="1 day ago" +"%Y-%m" )"
yyyymmdd="$( date --date="1 day ago" +"%Y-%m-%d" )"

for logfile in /var/log/*-$yyyymmdd.log; do
  tar -r -C /var/log -f "/data/logs/logfiles-$yyyymm.tar" "${logfile##*/}" &&
  rm "${logfile##*/}"
done

Флаг -r указывает tar добавлять записи в архив. Флаг -C используется для указания tar изменить каталог на / var / log перед доступом к файлам журнала. Флаг -f указывает расположение архива. $ {logfile ## * /} будет расширен до базового имени (имени файла без пути) файла журнала (его можно заменить на $ (базовое имя «$ logfile») ) .

В начале каждого месяца вы можете сжимать архив файлов журнала за предыдущий месяц с помощью

#!/bin/sh

yyyymm="$( date --date="1 month ago" +"%Y-%m" )"

gzip --best "/data/logs/logfiles-$yyyymm.tar"

. Это немного сложнее, чем просто выполнять

cd /var/log &&
tar -c -z -f /data/logs/logfiles-2016-08.tar.gz *-2016-08-??.log &&
rm *-2016-08-??.log

один раз в месяц, но тем не менее могут быть причины для этого. .

Примечание: файл может быть добавлен в архив с помощью tar -r , но архив не может быть сжатым архивом в то время (GNU tar ] может это поддержать). Если архива не существует, он будет создан. Также обратите внимание, что для моих примеров выше требуется дата GNU .

1
28.01.2020, 02:14

Ответ на исходный вопрос

Решение состоит в том, чтобы не использовать цикл для . Он перезаписывает файл каждый раз. Вместо этого используйте:

tar -zcvf server2.tgz server.log.2016-07-05 server.log.2016-07-06

Это добавляет столько файлов, сколько вы указываете в командной строке, в тот же архив.

Ответ на измененный вопрос

Для сжатия всех файлов за июль:

tar -zcvf server2.tgz server.log.2016-07-*

Или, чтобы сжать все файлы за предыдущий месяц, независимо от того, что это было:

tar -zcvf server2.tgz server.log.$(date "+%Y-%m" --date '1 month ago')-*
3
28.01.2020, 02:14

Теги

Похожие вопросы