Подтвердить что ты не робот

Tar: файл изменен, когда мы его читаем

Я использую make и tar для резервного копирования. При выполнении make файла команда tar показывает file changed as we read it. В этом случае

  • пакет tar доступен, когда появляется предупреждение
  • но он останавливает команду tar для следующей резервной копии
  • файл с предупреждением на самом деле не меняется - действительно странно, что предупреждение появляется
  • файлы с предупреждением появляются случайным образом, я имею в виду, каждый раз, когда я запускаю свой make файл, файлы с предупреждением различаются.
  • --ignore-failed-read не помогает. Я использую tar 1.23 в MinGW
  • Я просто поменял свой компьютер на WIN7 64 бит. script хорошо работает в старой версии WIN7 32 бит. Но версия tar не такая новая, как 1.23.

Как я могу остановить предупреждение tar, чтобы остановить резервное копирование после предупреждения?


Изменить-2: это может быть причина

Как я уже говорил выше, оболочка bash script хорошо работала на моем старом компьютере. Сравнивая со старым компьютером, версия msys отличается. Так же и версия tar-команды. На старом компьютере tar равен 1,13.19, а на новом компьютере - 1,23. Я скопировал старую команду tar без копирования ее зависимости msys-1.0.dll на новый компьютер и переименовал ее в tar_old. И я также обновил команду tar в оболочке script и запустил script. Тогда все в порядке. Таким образом, казалось, что проблема заключается в команде tar. Я уверен, что ни один файл не изменен при тарировании. Это ошибка для команды tar в новой версии? Я не знаю.


Изменить-1: добавить дополнительные сведения

Резервная копия вызывается оболочкой bash script. Он сканирует целевой каталог и создает make файл, а затем вызывает make для использования tar-команды для резервного копирования. Далее следует типичный make файл, созданный оболочкой bash script.

#--------------------------------------------
# backup VC
#--------------------------------------------
# the program for packing
PACK_TOOL=tar

# the option for packing tool
PACK_OPTION=cjvf

# M$: C driver
WIN_C_DIR=c:

# M$: D driver
WIN_D_DIR=d:

# M$: where the software is
WIN_PRG_DIR=wuyu/tools
# WIN_PRG_DIR=

# where to save the backup files
BAKDIR=/home/Wu.Y/MS_bak_MSYS

VC_FRAMEWORK=/home/Wu.Y/MS_bak_MSYS/tools/VC/VC_framework.tar.bz2
VC_2010=/home/Wu.Y/MS_bak_MSYS/tools/VC/VC_2010.tar.bz2

.PHONY: all

all: $(VC_FRAMEWORK) $(VC_2010)

$(VC_FRAMEWORK): $(WIN_C_DIR)/$(WIN_PRG_DIR)/VC/Framework/*
    @$(PACK_TOOL) $(PACK_OPTION) "[email protected]" --ignore-failed-read /c/$(WIN_PRG_DIR)/VC/Framework
$(VC_2010): $(WIN_C_DIR)/$(WIN_PRG_DIR)/VC/VS2010/*
    @$(PACK_TOOL) $(PACK_OPTION) "[email protected]" --ignore-failed-read /c/$(WIN_PRG_DIR)/VC/VS2010

Как вы можете видеть, пакет tar хранится в ~/MS_bak_MSYS/tools/VC/VC_2010.tar.bz2. Я запускаю script в ~/qqaa. ~/MS_bak_MSYS исключается из команды tar. Таким образом, tar файл, который я создаю, не находится внутри каталога, который я пытаюсь поместить в файл tar. Вот почему мне было странно, что предупреждение появилось.

4b9b3361

Ответ 1

Я также сталкиваюсь с сообщениями tar, "измененными по мере их чтения". Для меня это сообщение произошло, когда я делал tar файл файловой системы Linux в среде сборки bitbake. Эта ошибка была спорадической.

Для меня это произошло не из-за создания tar файла из того же каталога. Я предполагаю, что на самом деле файл был перезаписан или изменен во время создания файла tar.

Сообщение представляет собой предупреждение, и оно все еще создает файл tar. Мы все еще можем подавить это предупреждающее сообщение, установив опцию

--warning=no-file-changed

(http://www.gnu.org/software/tar/manual/html_section/warnings.html )

Тем не менее, возвращаемый кодом возврата в tar является "1" в случае с предупреждающим сообщением: http://www.gnu.org/software/tar/manual/html_section/Synopsis.html

Итак, если мы вызываем tar файл из некоторой функции в скриптах, мы можем обработать код выхода примерно так:

set +e 
tar -czf sample.tar.gz dir1 dir2
exitcode=$?

if [ "$exitcode" != "1" ] && [ "$exitcode" != "0" ]; then
    exit $exitcode
fi
set -e

Ответ 2

Если вам нужна помощь в отладке такой проблемы, вам необходимо предоставить правило make или, по крайней мере, выписанную команду tar. Как мы можем увидеть, что не так с командой, если нет команды для просмотра?

Однако в 99% случаев такая ошибка означает, что вы создаете файл tar внутри каталога, который вы пытаетесь поместить в файл tar. Итак, когда tar пытается прочитать каталог, он находит файл tar в качестве члена каталога, начинает его читать и записывает в tar файл, и поэтому между временем, когда он начинает читать tar файл и когда он заканчивается чтение tar файла, tar файл был изменен.

Итак, например, что-то вроде:

tar cf ./foo.tar .

Невозможно "остановить" это, потому что это не так. Просто поместите файл tar в другое место при его создании или найдите другой способ (используя --exclude или что-то еще), чтобы опустить tar файл.

Ответ 3

Хотя его очень поздно, но у меня недавно была такая же проблема.

Проблема связана с тем, что dir . изменяется при создании xyz.tar.gz после запуска команды. Существует два решения:

Решение 1: tar не будет возражать, если архив создается в любом каталоге внутри .. Могут быть причины, по которым невозможно создать архив вне рабочего пространства. Работал вокруг него, создав временный каталог для размещения архива как:

mkdir artefacts
tar -zcvf artefacts/archive.tar.gz --exclude=./artefacts .
echo $?
0

Решение 2: Это мне нравится. создайте файл архива перед запуском tar:

touch archive.tar.gz
tar --exclude=archive.tar.gz -zcvf archive.tar.gz .
echo $?
0

Ответ 4

Вот один лайнер для игнорирования статуса выхода tar, если он равен 1. Нет необходимости set +e, как в sandeep script. Если статус выхода tar равен 0 или 1, этот однострочный лайнер вернется с статусом выхода 0. В противном случае он вернется с статусом выхода 1. Это отличается от sandeep script, где исходное значение статуса выхода сохраняется, если оно отличается от 1.

tar -czf sample.tar.gz dir1 dir2 || [[ $? -eq 1 ]]